繁体   English   中英

python子类访问父类的类变量

[英]python subclass access to class variable of parent

得知子类的类变量无法访问父类的类变量而没有特别指出父类的名称,我感到很惊讶:

>>> class A(object):
...     x = 0
... 
>>> class B(A):
...     y = x+1
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in B
NameError: name 'x' is not defined
>>> class B(A):
...     y = A.x + 1
... 
>>> B.x
0
>>> B.y
1

为什么在定义By中,我必须引用Ax,而不仅仅是x? 这与我对实例变量的直觉是相反的,并且因为在定义B之后我可以引用Bx。

Python的裸名作用域规则非常简单明了:首先是本地名称空间,然后是(如果有的话)外部函数(在其中嵌套当前函数),然后是全局函数,最后是内置函数。 查找裸名时,所有这些都将发生,并且无需记住或应用任何复杂的规则(也无需使用Python编译器来执行更复杂的规则)。

每当您想要进行不同的查找时,都将使用限定名称而不是名。 合格名称的功能要强大得多,因为查找始终可以委托给可以请求其属性的对象,并且这些对象可以实现所需的任何查找规则。 特别是,在一个类中的实例方法, self.x是问 self对象查找属性名称'x' -并且在查找它可以委托给类,包括继承的概念的实施(以及多重继承,方法解析顺序等)。

类的主体 (与类中定义的方法的主体相对) 创建类对象或绑定其名称之前(特别是在定义任何基础之前)作为class语句的一部分执行作为基础-尽管在提及裸名时,无论如何最新的细节都没关系!

因此,在您的示例中,在类B ,使用通用规则查找裸名x -它是在本地绑定的名称吗? 如果否,是否将其绑定到嵌套此作用域的任何外部函数中? 如果不是,是绑定为全局对象还是内置对象? 如果以上都不是,则使用有问题的裸名当然会导致名称错误异常。

由于您想要的查找顺序与裸名查找规则普遍执行的查找顺序不同,因此显然您需要使用限定名,而不是裸名; 片刻的反思将清楚地表明,“一个显而易见的选择”为一名合格的名称来使用你的目的必须是Ax -因为你希望它要查找(基地没有在任何地方记录是的那一点,毕竟……将是通常为type的元类,当在类体执行完之后被调用时,它将作为其工作的一部分进行碱基绑定!

有些人非常热衷于查找裸名的其他“魔术”规则,以至于他们忍受不了Python的这一方面(我相信,最初是受Modula-3启发,这是一种鲜为人知的语言,在理论学家中已经考虑过了';;-)-必须在方法中编写self.x来指定必须在self上查找x ,而不是使用通用裸名规则,例如,使此类人发胖。

我,我喜欢裸名查找规则的简单性和通用性,并且我喜欢在需要任何其他形式的查找的任何时间使用合格名称而不是裸名...但是,我疯狂地爱上它并不是一个秘密Python(我有自己的抱怨-例如, global x总是使我的皮肤爬行,我更愿意在其中编写global.x ,即让global成为“当前执行模块”的内置名称...我确实喜欢合格的名字!-),对吗?-)

在Python中,在创建类之前,将在其自己的名称空间中执行类的主体(此后,该名称空间的成员将成为该类的成员)。 因此,当解释器达到y = x + 1时,此时B类还不存在,因此没有父类。

有关更多详细信息,请参见http://docs.python.org/reference/compound_stmts.html#class-definitions

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM