为何无法声明式覆盖类__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
相关产品推荐
相关产品推荐

