【发布时间】:2018-08-09 13:39:55
【问题描述】:
在 C++ 中,特定类的所有对象都有自己的数据成员,但共享成员函数,内存中只存在一份副本。 Python 的情况是否相同,或者类的每个实例都存在不同的方法副本?
【问题讨论】:
在 C++ 中,特定类的所有对象都有自己的数据成员,但共享成员函数,内存中只存在一份副本。 Python 的情况是否相同,或者类的每个实例都存在不同的方法副本?
【问题讨论】:
让我们一起来寻找答案,通过一个简单的测试:
class C:
def method(self):
print('I am method')
c1 = C()
c2 = C()
print(id(c1.method)) # id returns the address
>>> 140161083662600
print(id(c2.method))
>>> 140161083662600
这里是id(obj):
返回对象的标识。
这保证在同时存在的对象中是唯一的。 (CPython 使用对象的内存地址。)
【讨论】:
是的 - 内存中只存在该方法的一份副本:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... def test():
... return 1
...
>>> a = A()
>>> b = A()
>>> id(a.test)
140213081597896
>>> id(b.test)
140213081597896
【讨论】:
是的,对于类方法和实例方法,函数位于所有实例的相同的内存槽中。
但是您将无法覆盖该方法并影响其他实例,通过覆盖您只需向实例 dict 属性添加新条目(有关查找的更多上下文,请参阅class attribute lookup rule?) .
>>> class A():
... def x():pass
...
>>> s = A()
>>> d = A()
>>> id(s.x)
4501360304
>>> id(d.x)
4501360304
【讨论】: