Python Deepcopy .. вид - PullRequest
       1

Python Deepcopy .. вид

4 голосов
/ 14 января 2012

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

Пример: [[1, <SomeObj>], <OtherObj>]

Я хочу глубоко скопировать первый список (и, конечно, 1), но не SomeObj или OtherObj. Они должны оставаться в качестве референций.

Возможно ли это сделать с помощью какой-то функции, с которой я не знаком или мне нужно написать свою собственную функцию? ...

Ответы [ 3 ]

4 голосов
/ 14 января 2012

Вы можете сделать это с помощью copy.deepcopy довольно легко, переопределив метод __deepcopy__ в каждом из классов, в которых он вам нужен. Если вам нужно различное поведение копирования в зависимости от ситуации, вы можете просто установить функцию __deepcopy__ во время выполнения, а затем сбросьте его:

import copy
class OtherObject(object):
    pass

l = [[1, 2, 3], [4, 5, 6], OtherObject()]
# first, save the old deepcopy if there is one
old_deepcopy = None
if hasattr(OtherObject, __deepcopy__):
    old_deepcopy = OtherObject.__deepcopy__

# do a shallow copy instead of deepcopy
OtherObject.__deepcopy__ = lambda self, memo: self
l2 = copy.deepcopy(l)
# and now you can replace the original behavior
if old_deepcopy is not None:
    OtherObject.__deepcopy__ = old_deepcopy
else:
    del OtherObject.__deepcopy__

>>> l[0] is l2[0]
False
>>> l[1] is l2[1]
False
>>> l[2] is l2[2]
True
3 голосов
/ 14 января 2012

Насколько я знаю, для этого нет никакой утилиты. Встроенные модули copy и deepcopy требуют, чтобы объекты предоставляли свои собственные методы __copy__ и __deepcopy__ для переопределения поведения по умолчанию. ИМХО, что не очень хорошая идея, поскольку вы не всегда хотите получать копии одного и того же типа ...

Однако написание функции для этого не должно быть трудным. Вот пример, который работает для списков, кортежей и диктов:

def mycopy(obj):
    if isinstance(obj, list):
        return [mycopy(i) for i in obj]
    if isinstance(obj, tuple):
        return tuple(mycopy(i) for i in obj)
    if isinstance(obj, dict):
        return dict(mycopy(i) for i in obj.iteritems())
    return obj
1 голос
/ 14 января 2012

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

Я думаю, вы должны написать небольшую рекурсивную функцию для этого (до 20 строк).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...