9

既に持っている (に保存されている) シンボルを追跡するシンボル タイプを実装し、_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か?

どうもありがとう!

4

3 に答える 3

9

1 つの問題は、deepcopyどのcopy引数を に渡すかを知る方法が__new__ないため、コンストラクタ引数を必要としないクラスでのみ機能することです。

__init__引数を持つことができる理由__init__は、オブジェクトをコピーするときに呼び出されるのではなく__new__、新しいオブジェクトを作成するために呼び出す必要があるためです。

したがって、コピーを制御したい場合は、特別なメソッド__copy____deepcopy__メソッドを定義する必要があります。

def __copy__(self):
    return self

def __deepcopy__(self, memo):
    return self

ところで、シングルトンであり、Python では実際には必要ありません。

于 2012-05-16T16:25:24.340 に答える
1

Symbol インスタンスをシングルトンにしたいようです。ただし、Deepcopy は、インスタンスの正確なコピー、つまり元のインスタンスと等しい別のインスタンスが必要な場合に使用することになっています。

したがって、ここでの使用法は、deepcopy の目的と矛盾しています。とにかく機能させたい場合は、Symbolで__deepcopy__メソッドを定義できます。

于 2012-05-16T15:21:23.813 に答える
0

定義__getnewargs__— そうすれば、 と だけでなくcopydeepcopyもできるようになりpickleます。

于 2015-03-25T08:59:05.097 に答える