0

オブジェクトの最後の参照を削除しようとすると、奇妙な問題が発生します。

コードは次のとおりです。

import sys
import weakref

class Ref:

    def __init__(self, name):
        self.name = name
        self.ref = []

    def reference(self, obj):
        name = obj.name
        self.ref.append(
            weakref.ref(obj, lambda wref: print('{!r} is dead.'.format(name))))


a = Ref('a')
b = Ref('b')
c = Ref('c')
d = Ref('d')

a.reference(b)
b.reference(c)
c.reference(d)
d.reference(a)

print('reference count before killed:', sys.getrefcount(d.ref[0]()))
del a
print('reference count after killed:', sys.getrefcount(d.ref[0]()))

出力は次のとおりです。

reference count before killed: 2
'a' is dead.
reference count after killed: 1547
'd' is dead.
'c' is dead.

しかし、ときどき (完全にランダムです)'d' is dead.または'c' is dead.(しかし決して'b' is dead.) のみ、またはこれらのメッセージをまったく受信しませんでした。

だから私の最初の質問は、この奇妙な参照カウントとは何1547ですか? そして、それはどこから来たのですか?

2 つ目は、インスタンスを殺すと、aこのランダムな「他のインスタンスを殺す」効果が生じるのはなぜですか?

4

1 に答える 1

2

aGC した後、d.ref[0]()を生成しNoneます。そのため、削除後に 1547 の参照カウントが得られaます。結局、収集されたオブジェクトの refcount を要求することはできませんでしたね?

candの奇妙な削除dは、Python が、インタープリターが終了したときにオブジェクトが生きているかどうかを保証しないためです。通常の破棄プロセスを経ます。bc、およびdは、スクリプトの最後ですべて生きています。場合によっては、GC が正常に行われ、weakref コールバックが実行されます。時々、そうはなりません。Python はここで約束をしません。

于 2013-09-17T01:20:16.303 に答える