尝试修改装饰器以不使用 a weakref,我偶然发现了以下行为:
import weakref
class descriptor(object):
    def __get__(self, instance, owner):
        return proxy(instance)
class proxy(object):
    def __init__(self, instance):
        self.instance = instance
    def __iadd__(self, other):
        return self
class A(object):
    descr = descriptor()
def is_leaky(test_fn):
    a = A()
    wr = weakref.ref(a)
    test_fn(a)
    del a
    return wr() is not None
def test1(a):
    tmp = a.descr
    tmp += object()
def test2(a):
    a.descr += object()
print(is_leaky(test1))  # gives False
print(is_leaky(test2))  # gives True!!!
这对我来说似乎很奇怪,因为我希望两种情况的行为相同。此外,根据我对引用计数和对象生命周期的理解,我确信在这两种情况下都应该释放对象。
我已经在 python2.7 和 python3.3 上测试过它。
这是错误还是故意行为?有没有办法让两个调用都有预期的结果(释放有问题的对象)?
我不想使用weakrefinproxy因为这会破坏绑定方法的正确对象生命周期语义:
a = A()
descr = a.descr
del a   # a is kept alive since descr is a bound method to a
descr() # should execute a.descr() as expected