循環参照を持つ Python クラスのファイナライザーを作成しようとしています。弱い参照のコールバックが最適な方法であることがわかりました。残念ながら、コールバックとして使用するラムダは決して呼び出されないようです。たとえば、次のコードを実行します。
def del_A(name):
print('An A deleted:' + name)
class A(object):
def __init__(self, name):
print('A created')
self.name = name
self._wr = weakref.ref(self, lambda wr, n = self.name: del_A(n))
class B(object):
def __init__(self):
print('B created')
if __name__ == '__main__':
a = A('a1')
b = B()
a.other = b
b.other = a
戻り値:
A created
B created
循環参照を削除すると、ラムダ コールバックが機能します (「An A deleted: a1」が出力されます)。単純な関数呼び出しでラムダを置き換えることも機能しますが、コールバックを呼び出すときではなく、弱参照を初期化するときにパラメーター値が固定されます。
self._wr = weakref.ref(self, del_A(self.name))
...
a = A('a1')
a.name = 'a2'
b = B()
a.other = b
b.other = a
戻り値:
A created
An A deleted:a1
B created
ラムダコールバックが循環参照で機能しない理由は何ですか?