Python: реализация конструкторов мелкой и глубокой копии

В большинстве ситуаций легко реализовать конструкторы копирования (или перегруженный оператор присваивания) в С++, поскольку существует концепция указателей. Тем не менее, я довольно смущен тем, как реализовать мелкую и глубокую копию в Python.

Я знаю, что в одной из библиотек есть специальные команды, но они не работают над классами, которые вы написали сами. Итак, каковы общие способы реализации?

P.S. Будет оценен процесс отображения некоторых базовых структур данных (связанный список или дерево).

EDIT: Спасибо, они работали, это была моя ошибка в синтаксисе. Я очень заинтересован в перезаписывании этих функций с помощью __copy__() и __deep_copy()__. Например. как я могу сделать глубокую копию, не зная, какой тип информации находится в структуре данных?

Ответ 1

Модуль python copy может повторно использовать модуль pickle, чтобы позволить классам настраивать поведение копирования.

По умолчанию для экземпляров пользовательских классов следует создать новый пустой класс, заменив атрибут __class__, затем на мелкие копии, просто обновите __dict__ на копии со значениями из оригинала. Глубокая копия вместо этого заменяется на __dict__.

В противном случае вы укажете метод __getstate__() для возврата внутреннего состояния. Это может быть любая структура, которую ваш класс __setstate__() может принять снова.

Вы также можете указать методы __copy__() и/или __deepcopy__() для управления только режимом копирования. Ожидается, что эти методы будут выполнять все само копирование, методу __deepcopy__() передается memo-отображение для перехода к рекурсивным вызовам deepcopy().

Примером может быть:

from copy import deepcopy

class Foo(object):
    def __init__(self, bar):
        self.bar = bar
        self.spam = expression + that * generates - ham   # calculated

    def __copy__(self):
        # self.spam is to be ignored, it is calculated anew for the copy
        # create a new copy of ourselves *reusing* self.bar
        return type(self)(self.bar)

    def __deepcopy__(self, memo):
        # self.spam is to be ignored, it is calculated anew for the copy
        # create a new copy of ourselves with a deep copy of self.bar
        # pass on the memo mapping to recursive calls to copy.deepcopy
        return type(self)(deepcopy(self.bar, memo))

В этом примере определяются пользовательские скобки копирования для предотвращения копирования self.spam, так как новый экземпляр будет вычислять его заново.