В соответствии с документацией для модуля Weakref:
В дальнейшем, термине референт означает объект, на который ссылается слабой ссылкой.
Слабая ссылка на объект не достаточно, чтобы поддерживать жизнь объекта: когда только оставшиеся ссылки на референта являются слабыми ссылками, мусор коллекции бесплатно уничтожить референта и повторно использовать память для что-то другое.
Что происходит с MyCallbackA, что вы держите ссылку на него в случаях А, благодаря -
self.MyCallbackA = MyCallbackA
Теперь нет никаких ссылок на связанный метод MyCallbackB в вашем коде. Он поддерживается только в классе .__ __.__ dict__ как несвязанный метод. В принципе, связанный метод создается (и возвращается вам), когда вы делаете self.methodName. (AFAIK, связанный метод работает как свойство, используя дескриптор (только для чтения): по крайней мере для новых классов стилей. Я уверен, что что-то подобное, т. Е. Без дескрипторов, происходит для классов старого стиля. кто-то более опытный, чтобы проверить утверждение о классах старого стиля.) Итак, self.MyCallbackB умирает, как только создается слабыйref, потому что нет сильной ссылки на него!
Мои выводы основаны на: -
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
Примечание:
Я попытался проверить это для классов старого стиля. Оказалось, что "печать a.test_a .__ get__" выходы -
<method-wrapper '__get__' of instancemethod object at 0xb7d7ffcc>
для новых и старых классов стилей. Таким образом, это не может быть дескриптор, просто что-то вроде дескриптора. В любом случае, дело в том, что объект связанного метода создается, когда вы присоединяете метод экземпляра через self, и, если вы не поддерживаете сильную ссылку на него, он будет удален.
Для питона 3 заменить '' item.im_func' с товаром .__ func__' и '' item.im_self' с пунктом .__ self__' – lou
Может нужно '' Защита __eq __ (я, другой): вернуться другое() == self() ''? Это лучший образец сравнения? (и, вероятно, '' __ne__'' как обратное) – Rafe