繁体   English   中英

如何在派生类中引用基类'属性?

[英]How to reference a base class' attribute in derived class?

我可以做这个:

class Blah2:
    atttr = 5
    aa = atttr


ob = Blah2
print(ob.aa)

http://ideone.com/pKxMc2

所以我假设我也可以这样做:

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类定义体以外的任何位置,你必须使用类(或类的实例)来引用它: Cac().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.

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