同一对象的同一绑定方法为何ID相等?
Python绑定方法的
is与id困惑解析 最近碰到几个很有意思的问题,都是关于Python里对同一对象的同一绑定方法执行is测试时出现的意外行为。咱们拿一个典型场景来拆解:
首先定义这么一个简单的类:
class A(object): def foo(self): pass
当我们创建类的实例a = A()后,执行a.foo is a.foo,结果居然是False!这看起来有点反常识——明明是同一个实例的同一个方法,为什么is判断会不相等?
原因其实很直白:每次访问实例的绑定方法时,Python都会动态创建一个全新的method对象。这两次a.foo调用生成的是两个完全独立的对象,所以用来判断对象同一性的is运算符,自然会返回False。
这时候又会引出另一个疑问:既然这两个是不同的对象,那为什么执行id(a.foo) == id(a.foo)会返回True呢?
这就得说到Python里id()函数和垃圾回收的机制了:id()返回的是对象在内存中的地址,但如果一个对象被创建后,没有任何变量去引用它,Python的垃圾回收会立刻回收这块内存空间。
在id(a.foo) == id(a.foo)这个表达式里:
- 第一个
a.foo生成的method对象,在id()获取完它的地址后,就没有任何引用指向它了,内存瞬间被释放; - 紧接着第二个
a.foo生成新的method对象,刚好复用了刚才被释放的那块内存地址,所以两次id()返回的数值就一模一样了。
咱们可以做个小实验验证这个逻辑:如果把两个绑定方法先赋值给变量,让它们保持引用,再看id就不一样了:
>>> m1 = a.foo >>> m2 = a.foo >>> id(m1) == id(m2) False
因为m1和m2都持有对各自method对象的引用,它们不会被立刻回收,内存地址自然是不同的。
内容的提问来源于stack exchange,提问作者AGN Gazer
相关产品推荐
相关产品推荐

