![](/img/trans.png)
[英]Python - How to get an attribute of a derived class using a method in the base class
[英]How to reference a base class' attribute in derived class?
我可以做这个:
class Blah2:
atttr = 5
aa = atttr
ob = Blah2
print(ob.aa)
所以我假设我也可以这样做:
class Blah1:
atttr = 5
class Blah2(Blah1):
aa = atttr
ob = Blah2
print(ob.aa)
不,我不能: http : //ideone.com/6HS1MO
发出以下错误:
Traceback (most recent call last):
File "./prog.py", line 5, in <module>
File "./prog.py", line 6, in Blah2
NameError: name 'atttr' is not defined
为什么这不起作用以及如何使其工作?
类块作用域仅在类定义期间临时存在。 在类定义之后,您必须通过类对象访问该属性,即Blah1.atttr
。
这在执行模型部分中有记录。
exec()和eval()的类定义块和参数在名称解析的上下文中是特殊的。 类定义是可以使用和定义名称的可执行语句。 这些引用遵循名称解析的常规规则,但在全局命名空间中查找未绑定的局部变量。 类定义的名称空间成为类的属性字典。 类块中定义的名称范围仅限于类块 ; 它没有扩展到方法的代码块 - 这包括了解和生成器表达式,因为它们是使用函数作用域实现的。
您的问题修复如下:
class Blah1:
atttr = 5
class Blah2(Blah1):
aa = BLah1.atttr
但是,正如评论中指出的那样,这是一件很奇怪的事情。 现在你有了这个:
>>> ob = Blah2()
>>> assert ob.aa == ob.atttr
True
编辑:正如在wim的回答中所述,其原因在于如何在类定义中使用作用域。 当你这样做:
class C():
a = 1
它几乎相当于:
C = type('C', (), {}) # <--- dynamic class creation function
C.a = 1
正如你所看到的,为了访问a
类定义体以外的任何位置,你必须使用类(或类的实例)来引用它: Ca
或c().a
。 但请注意这个“问题”:
class C():
a = 1
c = C()
c.a = 2
print(C.a) # prints 1!!!
它打印1因为在上面的第二行之后,现在既有c
属性a
又有C
属性a
,它们是两个不同的对象:
>>> vars(c)
{'a': 2}
>>> vars(C)
{'a': 1}
如果您希望ca
不覆盖Ca
,则需要了解属性和描述符。 也许从这里开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.