質問

いプロジェクトというスを利用することにしたのだろうweakrefsとのコールバック、ないかなっている間違っています。て制作しました簡易試験の正確な行動をとても面白かったです。

それはこの試験にtest_aとが見込まれますが、そweakref。MyCallbackBが消えると、クラスを初期化し、呼び出しtest_b?思ったように、インスタンス(a)が存在するのを参考にします。MyCallbackB存在しているが、ださい。

import weakref

class A(object):
    def __init__(self):

        def MyCallbackA():
            print 'MyCallbackA'
        self.MyCallbackA = MyCallbackA

        self._testA = weakref.proxy(self.MyCallbackA)
        self._testB = weakref.proxy(self.MyCallbackB)

    def MyCallbackB(self):
        print 'MyCallbackB'

    def test_a(self):
        self._testA()

    def test_b(self):
        self._testB()

if __name__ == '__main__':
    a = A()    
    a.test_a()
    a.test_b()
役に立ちましたか?

解決

あなたは WeakMethod して欲しいです。

あなたのソリューションが動作しない理由の説明はレシピの議論で見つけることができます:

  バインドされた方法は、ファーストクラスのオブジェクトであるため、

バインド方法に通常weakref.refsはかなり、1が期待するように動作しません。 のバウンド方法weakrefs同じバインド方法にはいくつかの他の強力な参照が存在しない限りのデッドに到着している。

他のヒント

によると、ドキュメントのWeakrefモジュール:

以下では、長期リファレントのオブジェクトと より弱い。

弱参照オブジェクトではない なり、オブジェクト生きてい:時 そして残された参考文献を リファレントが弱参照のゴミ 収集する無料の破壊に リファレント-再利用メモリのための 一カ月もかかりました。

していただきましたことMyCallbackAがきを持参照がなくなってしばらくすると、インスタンスのり-

self.MyCallbackA = MyCallbackA

今、あなたの行き方法MyCallbackBにコードです。のみ開催されました。__クラス__.__dict__としての税方法です。基本的には、行き方法を作成し(返されます)がいます。methodName.(AFAIK、行き方法作品のような特性を記述子の読み込みのみ):少なくとも新しいスタイル。だから、類似するw/oの記述子が古いスタイル。んでい経験豊富な検証のための請求項につ古いスタイル。) います。MyCallbackB金型などのweakrefはありませんの強い参照です!

私の結論は基:-

import weakref

#Trace is called when the object is deleted! - see weakref docs.
def trace(x):
    print "Del MycallbackB"

class A(object):
    def __init__(self):

        def MyCallbackA():
            print 'MyCallbackA'
        self.MyCallbackA = MyCallbackA
        self._testA = weakref.proxy(self.MyCallbackA)
        print "Create MyCallbackB"
        # To fix it, do -
        # self.MyCallbackB = self.MyCallBackB
        # The name on the LHS could be anything, even foo!
        self._testB = weakref.proxy(self.MyCallbackB, trace)
        print "Done playing with MyCallbackB"

    def MyCallbackB(self):
        print 'MyCallbackB'

    def test_a(self):
        self._testA()

    def test_b(self):
        self._testB()

if __name__ == '__main__':
    a = A()  
    #print a.__class__.__dict__["MyCallbackB"] 
    a.test_a()

出力

をMyCallbackB
デMycallbackB
行っMyCallbackB
MyCallbackA

注意:
また検証にこの古いスタイル。そして"印刷。test_a.__車__" 出力-

<method-wrapper '__get__' of instancemethod object at 0xb7d7ffcc>

してもらうことにより、古いスタイル。そのあたりもする記述子には、何かの記述子。いずれの場合はバウンド-メソッドオブジェクトが作成したときにアクセスインスタンスメソッドを通じて自分なければ維持、強い参照がなくなってしばらくすると、削除されます。

他の回答が取り組むの元の質問ではなく、どちらかの回避策を提供していないか、外部サイトを参照してください。なぜ

この質問の重複としてマークされ、その多くは、このトピックのStackExchange上のいくつかの他の記事を通じて働いた後、私は最終的に簡潔な回避策に来ました。私は私が扱っていたオブジェクトの性質を知ったとき、私はweakrefモジュールを使用します。 (イベントコールバックを使用するときに私のコードで起こるよう)私が代わりにバインドされた方法で対処されるかもしれないとき、私は今weakref.refの直接の代替として、以下のWeakRefクラスを使用します()。私はではなく、Pythonの3.xの上、Pythonの2.7を含めてとPython 2.4でこれをテストしてみます。

class WeakRef:

    def __init__ (self, item):

        try:
            self.method   = weakref.ref (item.im_func)
            self.instance = weakref.ref (item.im_self)

        except AttributeError:
            self.reference = weakref.ref (item)

        else:
            self.reference = None


    def __call__ (self):

        if self.reference != None:
            return self.reference ()

        instance = self.instance ()

        if instance == None:
            return None

        method = self.method ()

        return getattr (instance, method.__name__)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top