Почему weakref не работает над этим связанным методом?

Был в состоянии решить эту проблему,

включил всю строку подключения и позволил роботу 3t проанализировать его, нажав From SRV.

См. Рис .:

enter image description here

11
задан Asa Ayers 1 March 2009 в 07:23
поделиться

2 ответа

Вы хотите WeakMethod.

Объяснение, почему Ваше решение не работает, может быть найдено в обсуждении рецепта:

Нормальные weakref.refs к связанным методам не вполне работают способ, которым каждый ожидает, потому что связанные методы являются первоклассными объектами; weakrefs к связанным методам мертвы по прибытию, если некоторая другая сильная ссылка к тому же связанному методу не существует.

12
ответ дан 3 December 2019 в 06:22
поделиться

Согласно документации для модуля Weakref:

В следующем термин референт означает объект, который упомянут слабой ссылкой.

Слабой ссылки на объект недостаточно для поддержания объекта: когда единственные остающиеся ссылки на референт являются слабыми ссылками, сборка "мусора" является бесплатной уничтожить референт и снова использовать его память для чего-то еще.

То, что происходит с MyCallbackA, - то, что Вы держите ссылку на него в экземплярах A, благодаря -

self.MyCallbackA = MyCallbackA

Теперь, нет никакой ссылки на связанный метод MyCallbackB в Вашем коде. Это сохранено только в a. __ класс __. __ dict __ как несвязанный метод. В основном связанный метод создается (и возвращается Вам), когда Вы делаете self.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
Del MycallbackB
Сделанное проигрывание с MyCallbackB
MyCallbackA

Примечание:
Я пытался проверить это для старых классов стиля. Оказалось что "печать test_a. __ добираются __" выводы -

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

и для новых и для старых классов стиля. Таким образом, это не может действительно быть дескриптор, просто что-то подобное дескриптору. В любом случае, дело в том, что объект связанного метода создается, когда Вы получаете доступ к методу экземпляра через сам, и если Вы не поддержите сильную ссылку к нему, он будет удален.

4
ответ дан 3 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: