python子类访问paren的类变量

2024-04-25 06:33:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我惊讶地发现,子类的类变量不能访问父类的类变量,除非明确指明父类的类名:

>>> 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

为什么在定义B.y时,我必须引用A.x而不仅仅是x?这与我对实例变量的直觉相反,因为我可以在定义B之后引用B.x。


Tags: inmost定义objectstdinlinecall子类
2条回答

Python对barenames的作用域规则非常简单和直接:首先是本地名称空间,然后是(如果有的话)嵌套当前名称空间的外部函数,然后是globals,最后是内置函数。这就是查找barename时所发生的一切,不需要记住或应用任何复杂的规则(也不需要Python编译器执行更复杂的规则)。

任何时候,如果需要其他查找,都将使用一个限定的名称,而不是一个裸的名称。限定名的功能要强大得多,因为查找总是可以委托给可以请求其属性的对象,这些对象可以实现它们需要的任何查找规则。特别是,在类中的实例方法中,self.x是请求self对象查找属性名'x'方法,在该查找中,它可以委托给类,包括继承概念的实现(以及多重继承、方法解析顺序等)。

类的body作为class语句的一部分执行,在创建类对象或绑定其名称之前(特别是在将任何基定义为基之前),尽管在引用不管怎样,都是赤裸裸的!-).

因此,在您的示例中,在类B中,使用通用规则查找barenamex——它是本地绑定的名称吗?如果否,它是否绑定在嵌套此作用域的任何外部函数中?如果没有,它是作为全局绑定的还是内置的?如果以上都不是,那么使用所讨论的barename当然会导致名称错误异常。

因为您想要一个不同的查找序列,而不是一个通用的barename查找规则,那么很明显,您需要使用一个限定名,而不是一个barename;片刻的反思将清楚地表明,限定名用于您的目的的“一个明显的选择”必须是A.x——因为这就是您想要的查过了(在那一点上碱基还没有被记录下来,毕竟。。。它将是元类,通常是type,当它在执行完类体之后被调用时,它将作为其工作的一部分来执行基绑定!-).

有些人对查找裸名的其他“神奇”规则如此执着,以至于他们无法忍受Python的这一方面(我相信,最初是受Modula-3的启发,Modula-3是一种鲜为人知的语言,在理论家的圈子里很受欢迎;-)--必须在一个方法中写入self.x,以指定x必须在self上查找,而不是使用通用的barename规则,例如,这会让这些人感到恼火。

我,我喜欢barename查找规则的简单性和通用性,我喜欢在任何时候使用限定名而不是barenames,我想任何其他形式的查找。。。但是,我疯狂地爱上Python并不是一个秘密(我有自己的牢骚——例如,global x因为一个语句总是让我的皮肤爬行,我宁愿在那里写global.x,也就是说,让global成为“当前正在执行的模块”的内置名称。。。我喜欢合格的名字!-),是吗?-)

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

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

相关问题 更多 >