【问题标题】:Instance methods in PythonPython 中的实例方法
【发布时间】:2018-08-09 13:39:55
【问题描述】:

在 C++ 中,特定类的所有对象都有自己的数据成员,但共享成员函数,内存中只存在一份副本。 Python 的情况是否相同,或者类的每个实例都存在不同的方法副本?

【问题讨论】:

标签: python instance-methods


【解决方案1】:

让我们一起来寻找答案,通过一个简单的测试:

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 使用对象的内存地址。)

【讨论】:

  • 首先感谢您的回答。但是你能告诉我为什么当我使用 print(id(c1.method))print(id(C.method)) 会给出不同的结果吗?这里发生了什么?
  • 啊,Python 的美丽等着你:) 在内部,Python 使用所谓的描述符机制来制作类属性、类方法、静态方法和...通常的类实例,也就是对象的方法。用 500 个字符来描述这是一个很长的话题 - 但这是一个很好的起点:docs.python.org/3.7/howto/descriptor.html 简而言之 - 在类主体中定义的函数通过绑定成为对象的方法。一个类的所有实例都使用(引用)单个绑定。
【解决方案2】:

是的 - 内存中只存在该方法的一份副本:

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

【讨论】:

    【解决方案3】:

    是的,对于类方法和实例方法,函数位于所有实例的相同的内存槽中。

    但是您将无法覆盖该方法并影响其他实例,通过覆盖您只需向实例 dict 属性添加新条目(有关查找的更多上下文,请参阅class attribute lookup rule?) .

    >>> class A():
    ...   def x():pass
    ... 
    >>> s = A()
    >>> d = A()
    >>> id(s.x)
    4501360304
    >>> id(d.x)
    4501360304
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-30
      • 2021-06-24
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 2023-03-13
      相关资源
      最近更新 更多