python子类访问父类的变量

python subclass access to class variable of parent

我很惊讶地发现,如果没有特别指明父类的类名,子类的类变量就无法访问父类的类变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> 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。


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

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

类的主体(与类中定义的方法的主体相反)在类对象被创建或其名称被绑定之前(特别是在任何基被定义为基之前)作为class语句的一部分执行,尽管在引用裸名称时,这个最新的细节永远都不重要!-)

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

既然你想要一个不同的查找顺序,而不是全然强制执行的裸名查找规则,那么很明显你需要使用一个限定名,而不是一个裸名;一瞬间的思考会清楚地表明,限定名的"一个明显的选择"必须是A.x,因为这就是你想要它在哪里被查找的地方。P(基地在那一刻还没有被记录下来,毕竟…它将是元类,通常是type,当类体执行完毕后调用它时,它将作为其工作的一部分进行基绑定!-)

有些人非常热衷于其他"神奇的"规则来查找裸名,以至于他们无法忍受Python的这一方面(我相信,最初受到modula-3的启发,modula-3是一种鲜为人知的语言,在理论家的圈子里被很好地考虑到;-)——必须用一种方法来写self.x,以规定x必须被定义为比如说,他们不使用通用的裸名规则,而是使用self,这让这些人疯狂。

我,我喜欢光名字查找规则的简单性和通用性,我喜欢在任何时候使用限定名而不是光名字,我想要任何其他形式的查找…但是,我疯狂地爱上了python,这不是一个秘密(我有自己的抱怨,比如global x,因为这句话总是让我的皮肤爬行,我宁愿写global.x,也就是说,global是"当前执行的模块"的内置名称……我喜欢有资格的名字!-)是吗?-)


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

有关更多详细信息,请参见http://docs.python.org/reference/compound-stmts.html类定义