python子类访问父类变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3648564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:04:56  来源:igfitidea点击:

python subclass access to class variable of parent

pythonsubclassclass-variables

提问by gaefan

I was surprised to to learn that a class variable of a subclass can't access a class variable of the parent without specifically indicating the class name of the 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

Why is it that in defining B.y I have to refer to A.x and not just x? This is counter to my intuition from instance variables, and since I can refer to B.x after B is defined.

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

采纳答案by Nathan Davis

In Python, the body of a class is executed in its own namespace before the class is created (after which, the members of that namespace become the members of the class). So when the interpreter reaches y = x+1, class B does not exist yet at that point and, therefore, has no parent.

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

For more details, see http://docs.python.org/reference/compound_stmts.html#class-definitions

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

回答by Alex Martelli

Python's scoping rules for barenames are very simple and straightforward: local namespace first, then (if any) outer functions in which the current one is nested, then globals, finally built-ins. That's all that ever happens when a barename is looked up, and there's no need to memorize or apply any complicated rules (nor is there any need for a Python compiler to enforce more complicated rules).

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

Any time you want a different lookup, you'll be using a qualifiedname, not a barename. Qualified names are vastly more powerful because the lookup can always be delegated to the objects whose attributes can be requested, and those object can implement whatever lookup rules they need. In particular, in an instance method within a class, self.xis theway to ask the selfobject to look up attribute name 'x'-- and in that lookup it can delegate to classes, including the implementation of the concept of inheritance (and multiple inheritance, method resolution order, and so on).

任何时候您想要不同的查找,您都将使用限定名称,而不是名称。限定名称的功能要强大得多,因为查找总是可以委托给可以请求其属性的对象,并且这些对象可以实现它们需要的任何查找规则。特别是,在一个类中的实例方法,self.x问路self对象查找属性名称'x'-并且在查找它可以委托给类,包括继承的概念(和多重继承,法决议的执行情况顺序等等)。

The bodyof a class (as opposed to the bodies of the methods defined in a class) executes as part of the classstatement, beforethe class object is created or its name is bound (in particular, before any of the bases have been defined as being bases -- though this latest detail can never matter when referring to barenames, anyway!-).

类的主体(与类中定义的方法的主体相反)作为class语句的一部分创建类对象或绑定其名称之前(特别是在任何基类定义为是基础——尽管这个最新的细节在提到裸名时永远无关紧要,无论如何!-)。

So, in your example, in class B, barename xis looked up with the universal rules -- is it a name bound locally? If no, is it bound in any outer function in which this scope is nested? If no, is it bound as a global or built-in? If none of the above, using the barename in question of course causes a name-error exception.

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

Since you want a different lookup sequence than the barename lookup rules universally enforce, then clearly you need to use a qualified name, not a barename; and a moment's reflection will clearly show that the "one obvious choice" for a qualified name to use for your purpose has to be A.x-- since that's where you wantit to be looked up (the bases haven't been recorded anywhere yetat that point, after all... it will be the metaclass, normally type, that will do the bases-binding as part of its job when it gets called afterthe class body is done executing!-).

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

Some people are so keenly attached to other "magical" rules for the lookup of barenames that they just can't stand this aspect of Python (originally inspired, I believe, by Modula-3, a little known language that's very well considered in theoreticians' circles;-) -- having to write self.xin a method to specify that xmust be looked up on selfrather than using the universal barename rules, for example, drives such people batty.

有些人非常热衷于查找裸名的其他“神奇”规则,以至于他们无法忍受 Python 的这一方面(我相信最初受到 Modula-3 的启发,这是一种鲜为人知的语言,在理论家中得到了很好的考虑) ' circles;-) -- 必须写self.x一个方法来指定x必须查找self而不是使用通用的裸名规则,例如,驱动这样的人。

Me, I love the simplicity and universality of the barename lookup rules, and I love using qualified names instead of barenames any time I want anyother form of lookup... but then, it's not a secret that I'm madly in love with Python (I have my own grumbles -- e.g., global xas a statement always makes my skin crawl, where I'd much rather write global.x, i.e., have globalbe a built-in name for "the currently executing module"... I dolove qualified names!-), is it?-)

我,我喜欢裸名查找规则的简单性和通用性,我喜欢在任何时候我想要任何其他形式的查找时使用限定名称而不是裸名……但是,这不是我疯狂爱上的秘密Python(我有自己的抱怨——例如,global x作为一个语句总是让我的皮肤爬行,我更愿意在那里写global.x,即,已经global成为“当前正在执行的模块”的内置名称......我喜欢限定名称!-),是吗?-)