群友 Jin 发出一段代码,
class Person:
def say(self):
pass
p1 = Person()
p2 = Person()
print(p1.say, id(p1.say))
print(p2.say, id(p2.say))
print(p1.say == p2.say) # False
print(p1.say is p2.say) # False
print(p1.say is p1.say) # False
print(id(p1.say) == id(p2.say)) # True
输出:
<bound method Person.say of <__main__.Person object at 0x7f6739300898>> 140081602502024
<bound method Person.say of <__main__.Person object at 0x7f67393005c0>> 140081602502024
False
False
False
True
python 官网上对 id 的解释
id(object)
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
CPython implementation detail: This is the address of the object in memory.
Raises an auditing event builtins.id with argument id.
我理解就是返回内存地址
StackOverFlow 上对 is 的解释: https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is 也就是引用比较,不就是比较内存地址?
群友 Sweeneys 发了一篇 StackOverFlo 的类似问题帖子: https://stackoverflow.com/questions/2906177/what-is-the-difference-between-a-is-b-and-ida-idb-in-python
回答中有一段话
b.test happens to have the same id as the bound method you had before and it's allowed to because no other objects have the same id now.
这意思就是说 a.test 被 gc 之后恰好释放的内存,正好被 b.test 所使用?所以才导致 True ?
于是群友 Jin 改成了如下代码,依然输出同样的结果,
import gc
gc.disable()
class Person:
def say(self):
pass
p1 = Person()
p2 = Person()
print(p1.say, id(p1.say))
print(p2.say, id(p2.say))
print(p1.say == p2.say) # False
print(p1.say is p2.say) # False
print(p1.say is p1.say) # False
print(id(p1.say) == id(p2.say)) # True
我尝试改成这样,依然输出同样的结果。
class Person:
def say(self):
pass
p1 = Person()
p2 = Person()
print(p1.say, id(p1.say))
print(p2.say, id(p2.say))
print(p1.say == p2.say) # False
print(p1.say is p2.say) # False
print(p1.say is p1.say) # False
p1_ref = p1.say
p2_ref = p2.say
print(id(p1.say) == id(p2.say)) # True
话说,python 中一个类中的 self 方法本身应该只在内存中占一个位置吧?然后调用的时候把对象地址 self 传进来调用,我记得 C++是这样的,虽然 Python 底层是 c 的 struct 实现的,但是也不至于这么弱智,同个类的不同对象的 self 方法占用多块内存吧?
