Python 2.7 在Python 2.7中手动构建ConfigParser的深层副本

Python 2.7 在Python 2.7中手动构建ConfigParser的深层副本,python-2.7,deep-copy,configparser,Python 2.7,Deep Copy,Configparser,刚刚开始我的Python学习曲线,在将一些代码移植到Python 2.7时遇到了障碍。在Python2.7中,似乎不再可能对ConfigParser的实例执行deepcopy()。另外,Python团队似乎对恢复这种功能不太感兴趣: 有人能提出一个优雅的解决方案来手动构建ConfigParser实例的deepcopy/副本吗 非常感谢,-Pete如果您需要新的ConfigParser独立副本,那么一个选项是: 拥有ConfigParser的原始版本 将配置文件序列化为临时文件或StringI

刚刚开始我的Python学习曲线,在将一些代码移植到Python 2.7时遇到了障碍。在Python2.7中,似乎不再可能对ConfigParser的实例执行deepcopy()。另外,Python团队似乎对恢复这种功能不太感兴趣:

有人能提出一个优雅的解决方案来手动构建ConfigParser实例的deepcopy/副本吗


非常感谢,-Pete

如果您需要新的ConfigParser独立副本,那么一个选项是:

  • 拥有ConfigParser的原始版本
  • 将配置文件序列化为临时文件或StringIO缓冲区
  • 使用该tmpfile或StringIO缓冲区创建新的ConfigParser

您已经完成了。

这只是用Python 3编写的Jan Vlcinsky answer的一个示例实现(我没有足够的声誉将此作为评论发布给Jan的answer)。非常感谢简朝着正确的方向努力

要将
base\u config
的完整(深度)副本复制到
new\u config
中,只需执行以下操作

import io
import configparser

config_string = io.StringIO()
base_config.write(config_string)
# We must reset the buffer ready for reading.
config_string.seek(0) 
new_config = configparser.ConfigParser()
new_config.read_file(config_string)

基于@Toenex answer,针对Python 2.7进行了修改:

import StringIO
import ConfigParser

# Create a deep copy of the configuration object
config_string = StringIO.StringIO()
base_config.write(config_string)

# We must reset the buffer to make it ready for reading.        
config_string.seek(0)        
new_config = ConfigParser.ConfigParser()
new_config.readfp(config_string)

前面的解决方案并不适用于所有python3用例。特别是,如果原始解析器正在使用副本,则副本可能无法正常工作。幸运的是,简单的解决方案是使用模块:


阅读本文后,我对config.ini更为熟悉

记录如下:

import io
import configparser


def copy_config_demo():
    with io.StringIO() as memory_file:
        memory_file.write(str(test_config_data.__doc__))  # original_config.write(memory_file)
        memory_file.seek(0)
        new_config = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
        new_config.read_file(memory_file)

    # below is just for test
    for section_name, list_item in [(section_name, new_config.items(section_name)) for section_name in new_config.sections()]:
        print('\n[' + section_name + ']')
        for key, value in list_item:
            print(f'{key}: {value}')


def test_config_data():
    """
    [Common]
    home_dir: /Users
    library_dir: /Library
    system_dir: /System
    macports_dir: /opt/local

    [Frameworks]
    Python: >=3.2
    path: ${Common:system_dir}/Library/Frameworks/

    [Arthur]
    name: Carson
    my_dir: ${Common:home_dir}/twosheds
    my_pictures: ${my_dir}/Pictures
    python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
    """
输出:

[Common]
home_dir: /Users
library_dir: /Library
system_dir: /System
macports_dir: /opt/local

[Frameworks]
python: >=3.2
path: /System/Library/Frameworks/

[Arthur]
name: Carson
my_dir: /Users/twosheds
my_pictures: /Users/twosheds/Pictures
python_dir: /System/Library/Frameworks//Python/Versions/>=3.2
希望对您有所帮助。

如果您使用的是Python 3(3.2+),则可以使用将源配置的部分和选项复制(实际上是深度复制)到另一个对象

您可以使用复制配置解析器的状态

下面是一个演示:

导入配置解析器
#深度复制的配置:
src_cfg=configparser.configparser()
src_cfg.添加_节(“A节”)
src_cfg[“A节”][“键1”]=“值1”
src_cfg[“A节”][“键2”]=“值2”
#目标配置
dst_cfg=configparser.configparser()
dst_cfg.read_dict(src_cfg)
dst_cfg.添加_节(“B节”)
dst_cfg[“B节”][“键3”]=“值3”
要显示生成的配置,您可以尝试:

导入io
输出=io.StringIO()
dst_cfg.写入(输出)
打印(output.getvalue())
你会得到:

[Section A]
key1 = value1
key2 = value2

[Section B]
key3 = value3

不适用于ExtendedInterpolation。请参阅替代解决方案。。。。而且它几乎适用于所有类型的对象。好把戏!
[Section A]
key1 = value1
key2 = value2

[Section B]
key3 = value3