Gul*_*zar 3 python binding closures
请考虑以下事项
class A(object):
def foo(self):
pass
a = A()
# accessing a's foo seems consistent
init1 = a.foo
init2 = a.foo
assert init1 == init2
assert id(a.foo) == id(a.foo)
# Or is it?
foos= [a.foo for i in range(10)]
ids = [id(foo) for foo in foos]
for i, id_ in enumerate(ids):
for j, id__ in enumerate(ids):
if i != j:
assert id_ != id__
Run Code Online (Sandbox Code Playgroud)
看来id(a.foo)可以等于id(a.foo)和不能等于id(a.foo),但我不明白什么时候相同,什么时候不同。
请解释一下这是怎么回事。
每次访问实例方法属性时都会发生函数到实例方法的转换,因此每次 id 都应该不同,至少在创建新对象的意义上是这样。(有关方法转换和描述符的详细信息,请参阅Python数据模型)
问题是这样做:
assert id(a.foo) == id(a.foo)
Run Code Online (Sandbox Code Playgroud)
有时,Python 垃圾收集器的工作速度非常快,即使在单个表达式中,两个不同的对象也可以具有相同的 id,因为该对象已经被回收一次id()。
如果你这样做:
assert id(init1) == id(init2)
Run Code Online (Sandbox Code Playgroud)
你会发现它们实际上有不同的 id。
更新:解决为什么:和init1 == init2是方法包装器对象引用同一类中的相同函数的问题,因此方法包装器认为它们相等。Trueinit1init2__eq__()