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

时间:2014-05-01 20:50:15

标签: python-2.7 deep-copy configparser

刚开始我的Python学习曲线,并且在将一些代码移植到Python 2.7时遇到了麻烦。看起来在Python 2.7中,不再可能对ConfigParser的实例执行deepcopy()。似乎Python团队对恢复这样的能力并不十分感兴趣:

http://bugs.python.org/issue16058

有人可以提出一个优雅的解决方案来手动构建ConfigParser实例的深层复制/复制吗?

非常感谢,-Pete

6 个答案:

答案 0 :(得分:6)

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

要将base_config的完整(深层)副本复制到new_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)

答案 1 :(得分:4)

基于@Toenex答案,针对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)

答案 2 :(得分:1)

如果您需要新的ConfigParser独立副本,则可以选择一个选项:

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

你完成了它。

答案 3 :(得分:0)

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

def deep_copy(config:configparser.ConfigParser)->configparser.ConfigParser:
    """deep copy config"""
    rep = pickle.dumps(config)
    new_config = pickle.loads(rep)
    return new_config

答案 4 :(得分:0)

阅读本文后,我对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

希望它对您有帮助。

答案 5 :(得分:0)

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

您可以使用 read_dict() 复制配置解析器的状态。

这是一个演示:

import configparser

# the configuration to deep copy:
src_cfg = configparser.ConfigParser()
src_cfg.add_section("Section A")
src_cfg["Section A"]["key1"] = "value1"
src_cfg["Section A"]["key2"] = "value2"

# the destination configuration
dst_cfg = configparser.ConfigParser()
dst_cfg.read_dict(src_cfg)
dst_cfg.add_section("Section B")
dst_cfg["Section B"]["key3"] = "value3"

要显示生成的配置,您可以尝试:

import io

output = io.StringIO()
dst_cfg.write(output)
print(output.getvalue())

你得到:

[Section A]
key1 = value1
key2 = value2

[Section B]
key3 = value3