通过实例与类访问方法时__dict__可用性差异及相关问题问询
为什么类方法有__dict__但实例绑定的方法没有?
要搞清楚这个问题,核心得先明白类里的方法和实例绑定的方法是两种完全不同的对象:
1. 类级别的方法是原生函数对象
当你通过MyClass.my_method访问时,拿到的是一个标准的function类型对象——和你用def直接定义的普通函数没区别。函数对象天生自带__dict__属性,专门用来存储动态添加的自定义属性,所以你能直接给它赋值MyClass.my_method.some_attribute = "xxx",这个属性就存在它的__dict__里。
2. 实例访问的是绑定方法(method)对象
当你通过my_class.my_method访问时,Python会自动创建一个绑定方法(method类型)对象。这个对象相当于一个“包装器”,把实例my_class和原函数MyClass.my_method绑定在了一起,调用它时会自动把实例作为第一个参数self传入。
但这种绑定方法对象是没有__dict__的,所以你没法直接给它动态添加属性。那为什么my_class.my_method.some_attribute能正常输出?因为绑定方法会把属性访问请求转发给底层的原函数,你访问的其实是MyClass.my_method上的属性,不是绑定方法自己的。
结合你的代码示例理解
print(my_class.my_method.some_attribute)能拿到值:本质是绑定方法代理到了原函数的some_attribute属性,不是它自己有这个属性。my_class.my_method.other_attribute = "xxx"报错:因为你试图给没有__dict__的绑定方法对象添加属性,Python直接抛出AttributeError。'__dict__' in dir(MyClass.my_method)返回True:因为这是函数对象,自带__dict__;而'__dict__' in dir(my_class.my_method)返回False:因为绑定方法对象没有这个属性。
总结
简单来说:
- 类直接访问的是函数对象,支持动态添加属性(有
__dict__) - 实例访问的是绑定方法对象,不支持动态添加属性(无
__dict__)
你看到的实例方法能访问类方法的属性,只是因为绑定方法做了属性转发,不是它自己拥有这些属性。
内容的提问来源于stack exchange,提问作者Zimzozaur
相关产品推荐
相关产品推荐

