You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法声明式覆盖类__name__属性?示例解析

为什么没法在类定义里直接覆盖__name__属性?

这个问题挺有意思的,我刚接触Python的时候也踩过类似的坑。先看你给出的例子:

>>> class Potato:
...     __name__ = 'not Potato'
...
>>> Potato.__name__ # 没生效
'Potato'
>>> Potato().__name__ # 但实例能拿到这个值
'not Potato'

本质原因是Python在创建类的过程中,会绕过类定义里的__name__赋值,直接给类对象设置这个特殊属性。

具体来说,当你写完类定义块执行后,Python会先运行块里的所有代码,把变量都放进一个临时类字典里——这时候__name__ = 'not Potato'确实被存进这个字典了。但紧接着,解释器会用type(或者你指定的元类)生成真正的类对象,在这个步骤里,type.__new__方法会把你写的类名(也就是Potato)作为参数,直接给新创建的类对象设置__name__属性,完全不管临时字典里已经存在的那个__name__值。

那为什么实例能拿到'not Potato'呢?因为类对象的__name__是它自己的实例属性(毕竟类本身是type的实例),当你访问Potato.__name__时,直接取的是这个属性;但类的__dict__里还留着你当初赋值的__name__,实例在查找属性时,会先找自己的字典,没有的话就去类的字典里找,自然就能拿到那个没被用到的值。你可以验证一下:

>>> '__name__' in Potato.__dict__
True
>>> Potato.__dict__['__name__']
'not Potato'
>>> Potato.__name__  # 直接取类对象的属性,和字典里的无关
'Potato'

如果真的想修改类的__name__,别在类定义里写,等类创建完之后直接赋值就行:

>>> Potato.__name__ = 'not Potato'
>>> Potato.__name__
'not Potato'

内容的提问来源于stack exchange,提问作者wim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:44:31