Python面试题:Python的对象方法是如何存储的?

不知道应该答 class method instance method 相关的知识,还是内存管理或 slots 相关的知识…
Python面试题:Python的对象方法是如何存储的?

3 回复

在Python中,对象的方法存储方式依赖于它是实例方法、类方法还是静态方法。核心机制是描述符(Descriptor)

1. 实例方法 当你定义一个实例方法时,它实际上存储在类字典里,而不是每个实例中。调用 obj.method() 时,Python通过描述符协议触发 method.__get__(obj, type(obj)),这会返回一个**绑定方法(bound method)**对象,该对象将实例 obj 作为第一个参数(self)预先绑定。

class MyClass:
    def instance_method(self):
        return self

obj = MyClass()
# 从类中获取的是未绑定的函数对象
print(MyClass.instance_method)  # <function MyClass.instance_method at 0x...>
# 从实例中获取的是绑定方法对象,self已绑定
print(obj.instance_method)      # <bound method MyClass.instance_method of <__main__.MyClass object at 0x...>>

2. 类方法 使用 @classmethod 装饰的方法也是存储在类字典中。描述符 classmethod__get__ 会返回一个绑定到类本身的方法,第一个参数是 cls

3. 静态方法 使用 @staticmethod 装饰的方法同样存储在类字典中。staticmethod 描述符的 __get__ 直接返回底层函数本身,不进行绑定。

总结一下:

  • 方法本身(函数对象) 总是存储在类的 __dict__ 中。
  • 当你通过实例访问方法时,Python的描述符协议自动将其转换为一个绑定方法对象,该对象包装了函数和具体的实例(或类)。
  • 这实现了内存高效(方法代码只存一份)和动态绑定(每次访问都绑定到当前实例)。

一句话建议: 理解描述符协议是掌握Python方法存储和绑定的关键。


感觉问的应该是类的知识。在类里定义一个方法,会在堆上开辟内存生成一个函数对象,并把这个对象名放在类的__dict__中。

class apple(object):

def price (self):
print ‘2’

def weight (self):
print '400g’

print apple.dict

{‘module’: ‘main’, ‘weight’: <function weight at 0x03868DB0>, ‘price’: <function price at 0x03868D70>, ‘dict’: <attribute ‘dict’ of ‘apple’ objects>, ‘weakref’: <attribute ‘weakref’ of ‘apple’ objects>, ‘doc’: None}

可见方法 price 和 weight 分别在堆上的不同位置。

#1 我跟面试官确认过的,他说的对象是指类的实例,对象的方法是指 实例的 methods,刚开始我也答的是 dict ,但是他说 dict 只是把对象属性返回出来了,而没有说清楚对象方法是怎么存储的。。。

回到顶部