Копирование на Python: как наследовать поведение копирования по умолчанию? - PullRequest
4 голосов
/ 15 июля 2010

Хорошо ... Это может быть глупый вопрос ... но я не могу найти ответ прямо сейчас!

Мне нужно реализовать копию объекта, для которого я хочу скопировать все атрибуты, кроме одного или двух, для которых я хочу полностью контролировать копию.

Вот стандартное поведение копирования для объекта:

>>> class test(object):
...     def __init__(self, arg):
...         self._a = arg
... 
>>> t = test(123999)
>>> t._a
123999
>>> tc = copy.copy(t)
>>> tc._a
123999

Что в основном означает, что все атрибуты скопированы. Что я хотел бы сделать, это повторно использовать это поведение следующим образом:

>>> class test(object):
...     def __init__(self, arga, argb):
...         self._a = arga
...         self._b = argb
...
...     def __copy__(self):
...         obj_copy = copy.copy(self) #NOT POSSIBLE OF COURSE => infinite recursion
...         obj_copy._b = my_operation(obj_copy._b)
...         return obj_copy

Надеюсь, вы поняли: я хочу повторно использовать поведение копирования объектов, но подключить свои собственные операции. Есть ли чистый способ сделать это (без необходимости for attr_name in dir(self): ...) ???

Ответы [ 3 ]

5 голосов
/ 15 июля 2010

Вы можете просто сделать:

def __copy__(self):
    clone = copy.deepcopy(self)
    clone._b = some_op(clone._b)
    return clone

Это будет работать, потому что deepcopy избегает рекурсии.Из документов Python :

Функция deepcopy () позволяет избежать этих проблем путем: сохранения словаря «памятки» объектов, уже скопированных во время текущего этапа копирования;и позволяя пользовательским классам переопределять операцию копирования или набор копируемых компонентов.

3 голосов
/ 15 июля 2010

Если у вас нет свойств & c, все состояние находится в __dict__, поэтому ...:

...     def __copy__(self):
...         obj_copy = object.__new__(type(self))
...         obj_copy.__dict__ = self.__dict__.copy()
...         obj_copy._b = my_operation(obj_copy._b)
...         return obj_copy
2 голосов
/ 15 июля 2010

Я хотел бы сделать это следующим образом - попробуйте:

import copy
class test(object):
    def __init__(self, **args):
        self.args = args

    def __copy__(self):
        obj_copy = copy.deepcopy(self)
        return obj_copy 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...