Python 类和对象中方法的内存地址

Python 类和对象中方法的内存地址,python,python-3.x,Python,Python 3.x,根据下面的代码 class A: def method(): pass obj1 = A() obj2 = A() print(hex(id(A.method))) print(hex(id(obj1.method))) print(hex(id(obj2.method))) 最后两条语句打印相同的地址,但第一条语句不打印 为什么在初始化对象时需要复制方法而不使用与类相同的地址?它没有复制方法 当您使用instance.method时,它会创建一个新的绑定方法对象

根据下面的代码

class A:
    def method():
        pass


obj1 = A()
obj2 = A()

print(hex(id(A.method)))
print(hex(id(obj1.method)))
print(hex(id(obj2.method)))
最后两条语句打印相同的地址,但第一条语句不打印


为什么在初始化对象时需要复制方法而不使用与类相同的地址?

它没有复制方法

当您使用
instance.method
时,它会创建一个新的
绑定方法
对象,将该方法绑定到该实例。这类似于不同环境中相同函数的多个闭包

请注意,
obj1.method
obj2.method
实际上不是相同的绑定方法对象。由于没有保存任何一个对象,第一个对象立即被丢弃,其地址用于第二个对象。您可以通过将它们指定给变量来防止这种情况

method1 = obj1.method
method2 = obj2.method
print(hex(id(method1)))
print(hex(id(method2)))
因为对象不能被垃圾收集,所以它们得到不同的ID


有关这方面的其他示例,请参见

Try
print(A.method,obj1.method)
,并注意其中的区别。这是因为一个是函数,另一个是绑定方法?没错。网上有很多关于方法/绑定方法的文档,有一点环顾四周严格来说,它们不是内存地址;它们只是对象标识符。(CPython使用地址作为实现细节,但不应将其视为内存地址。)是的,但这正是CPython用于对象标识符的内容。你不能以任何方式使用它;例如,您无法通过了解对象的标识符来获取对对象的引用。