Python面试题:Python的对象方法是如何存储的?
不知道应该答 class method instance method 相关的知识,还是内存管理或 slots 相关的知识…
Python面试题:Python的对象方法是如何存储的?
在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 只是把对象属性返回出来了,而没有说清楚对象方法是怎么存储的。。。

