Я понимаю различие между copy
по сравнению с. deepcopy
в модуле копии. Я использовал copy.copy
и copy.deepcopy
прежде успешно, но это - первый раз, когда я на самом деле пошел о перегрузке __copy__
и __deepcopy__
методы. Я уже Погуглил вокруг и просмотрел встроенные модули Python для поиска экземпляров __copy__
и __deepcopy__
функции (например. sets.py
, decimal.py
, и fractions.py
), но я все еще не на 100% уверен, что у меня есть он право.
Вот мой сценарий:
У меня есть объект конфигурации. Первоначально, я собираюсь инстанцировать одного объекта конфигурации со множеством значений по умолчанию. Эта конфигурация будет передана к нескольким другим объектам (чтобы гарантировать, чтобы все объекты запустились с той же конфигурации). Однако, после того как взаимодействие с пользователем запускается, каждый объект должен настроить свои конфигурации независимо, не влияя на конфигурации друг друга (который говорит мне, что я должен буду сделать deepcopys своей первоначальной конфигурации для раздавания).
Вот демонстрационный объект:
class ChartConfig(object):
def __init__(self):
#Drawing properties (Booleans/strings)
self.antialiased = None
self.plot_style = None
self.plot_title = None
self.autoscale = None
#X axis properties (strings/ints)
self.xaxis_title = None
self.xaxis_tick_rotation = None
self.xaxis_tick_align = None
#Y axis properties (strings/ints)
self.yaxis_title = None
self.yaxis_tick_rotation = None
self.yaxis_tick_align = None
#A list of non-primitive objects
self.trace_configs = []
def __copy__(self):
pass
def __deepcopy__(self, memo):
pass
Что правильный путь состоит в том, чтобы реализовать copy
и deepcopy
методы на этом объекте удостовериться copy.copy
и copy.deepcopy
дайте мне правильное поведение?
Рекомендации по настройке находятся в самом конце страницы документации :
Классы могут использовать одни и те же интерфейсы для контролировать копирование, которое они используют для контроль травления. Смотрите описание модуля pickle для получения информации о эти методы. Модуль копирования делает не использовать регистрацию copy_reg модуль.
Чтобы класс мог определить свой собственный копировать реализацию, он может определять специальные методы
__ copy __ ()
и__ deepcopy __ ()
. Первый призван реализовать мелкую копию операция; никаких дополнительных аргументов нет прошло. Последний призван реализовать операцию глубокого копирования; Это передается один аргумент, памятка Словарь. Если__ deepcopy __ ()
реализация должна сделать глубокий копия компонента, она должна вызывать функцияdeepcopy ()
с компонент в качестве первого аргумента и мемо-словарь в качестве второго аргумента.
Поскольку вы, похоже, не заботитесь о настройке травления, определение __ copy __
и __ deepcopy __
определенно кажется правильным путем для вас.
В частности, для вас. , __ copy __
(мелкая копия) в вашем случае довольно просто ...:
def __copy__(self):
newone = type(self)()
newone.__dict__.update(self.__dict__)
return newone
__ deepcopy __
будет аналогичным (принятие аргумента memo
arg), но до возврата ему пришлось бы вызвать self.foo = deepcopy (self.foo, memo)
для любого атрибута self.foo
, который требует глубокого копирования (по сути, атрибуты, которые являются контейнерами - списки, dicts , непримитивные объекты, которые содержат другие данные через свои __ dict __
s).
Я могу немного сбиться с толку, но здесь идет;
Из копии
docs ;
- Мелкая копия создает новый составной объект, а затем (насколько это возможно) вставляет в него ссылки на объекты, найденные в оригинале.
- Глубокая копия конструирует новый составной объект, а затем рекурсивно вставляет в него копии объектов, найденных в оригинале.
Другими словами: copy ()
скопирует только верхний элемент, а остальные оставит в качестве указателей на исходную структуру. deepcopy ()
будет рекурсивно копировать все.
То есть, deepcopy ()
- это то, что вам нужно.
Если вам нужно сделать что-то действительно конкретное, вы можете переопределить __ copy __ ()
или __ deepcopy __ ()
, как описано в руководстве. Лично я