Ручное построение глубокой копии ConfigParser в Python 2.7


Просто начинаю с моей кривой обучения Python и натыкаюсь на загвоздку в переносе некоторого кода до Python 2.7. Похоже, что в Python 2.7 больше невозможно выполнить deepcopy () на экземплярах ConfigParser. Кроме того, похоже, что команда Python не очень заинтересована в восстановлении такой возможности:

Http://bugs.python.org/issue16058

Может ли кто-нибудь предложить элегантное решение для ручного построения deepcopy / дубликата экземпляра ConfigParser?

Большое спасибо, - Пит

4 6

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)

Это просто пример реализации ответа Яна Влчинского, написанного на Python 3 (у меня недостаточно репутации, чтобы опубликовать это в качестве комментария к ответу Jans). Большое спасибо Яну за толчок в правильном направлении.

Чтобы сделать полную (глубокую) копию 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)

Если вам нужна новая независимая копия ConfigParser, то один из вариантов:

  • есть оригинальная версия ConfigParser
  • сериализуйте конфигурационный файл во временный файл или буфер StringIO
  • Используйте этот буфер tmpfile или StringIO для создания нового ConfigParser.

И вы это сделали.

Предыдущее решение не работает во всех случаях использованияpython3 . В частности, если исходный синтаксический анализатор использует расширенную интерполяцию, копия может не работать правильно. К счастью, простым решением является использование модуляpickle :

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