copy.deepcopy вызывает TypeError для объектов с самоопределяемым методом __new__()

Я хочу реализовать тип символа, который отслеживает уже имеющиеся символы (сохраненные в _sym_table), и вернуть их, если они существуют, или создать новые в противном случае. Код:

# -*- coding: utf-8 -*-

_sym_table = {}

class Symbol(object):
    def __new__(cls, sym):
        if sym not in _sym_table:
            return super().__new__(cls)
        else:
            return _sym_table[sym]

    def __init__(self, sym):
        self.sym = sym
        _sym_table[sym] = self

    def __str__(self):
        return self.sym

    def __cmp__(self, other):
        return self is other

    def __hash__(self):
        return self.sym.__hash__()

Но когда я вызываю copy.deepcopyв списке таких экземпляров Symbol, возникает исключение:

a = Symbol('a')
b = Symbol('b')
s = [a, b]
t = copy.deepcopy(s)

Сообщения об ошибках:

Traceback (most recent call last):
  File "xxx.py", line 7, in <module>
    t = copy.deepcopy(s)
  File "/usr/lib/python3.2/copy.py", line 147, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python3.2/copy.py", line 209, in _deepcopy_list
    y.append(deepcopy(a, memo))
  File "/usr/lib/python3.2/copy.py", line 174, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/usr/lib/python3.2/copy.py", line 285, in _reconstruct
    y = callable(*args)
  File "/usr/lib/python3.2/copyreg.py", line 88, in __newobj__
    return cls.__new__(cls, *args)
TypeError: __new__() takes exactly 2 arguments (1 given)

Итак, мои вопросы :

  • Как я могу сделать глубокую копию этих объектов с помощью самоопределяемых __new__методов?
  • Есть предложения о том, когда и как использовать copy.deepcopy?

Большое спасибо!

8
задан PJ.Hades 16 May 2012 в 12:51
поделиться