从子类内的父类访问属性

时间:2015-10-26 12:58:49

标签: python python-2.7 class inheritance

当我通过这样的子类从父类访问属性时,一切正常:

class A():
    a=1
    b=2

class B(A):
    c=3

d=B.a+B.b+B.c
print d

但是如果我尝试从子类中的父类访问这样的属性,那么它就不起作用了:

class A():
    a=1
    b=2

class B(A):
    c=3
    d=a+b+c
    print d

我收到错误:name 'a' is not defined

假设我有很多方程式,比如d = a + b + c(但更复杂),我无法编辑它们 - 我必须在B级" a" as" a&#34 ;, not" self.a"或" something.a"。但是,在方程式之前,我可以做A.a = a。但这并不是手动重新加载所有变量的最明智的方法。我想使用继承绕过它。可以或我应该手动完成所有操作吗?或者这个代码中可能是第3条路线?

2 个答案:

答案 0 :(得分:6)

在类定义期间,没有任何继承的属性可用:

>>> class Super(object):
    class_attribute = None
    def instance_method(self):
        pass


>>> class Sub(Super):
    foo = class_attribute



Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#7>", line 2, in Sub
    foo = class_attribute
NameError: name 'class_attribute' is not defined
>>> class Sub(Super):
    foo = instance_method



Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#9>", line 2, in Sub
    foo = instance_method
NameError: name 'instance_method' is not defined

您甚至无法使用super访问它们,因为子类的名称未在定义块*中定义:

>>> class Sub(Super):
    foo = super(Sub).instance_method



Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#11>", line 2, in Sub
    foo = super(Sub).instance_method
NameError: name 'Sub' is not defined

唯一的方法在定义时访问继承的属性是使用超类的名称显式地这样做:

>>> class Sub(Super):
    foo = Super.class_attribute


>>> Sub.foo is Super.class_attribute
True

或者您可以在类或实例方法中访问它们,但是您需要使用类的适当前缀(通常为cls)或实例(常规self)参数。

*对于任何想到“啊,但在3.x中你不需要super 的论据的人:

>>> class Sub(Super):
    foo = super().instance_method


Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    class Sub(Super):
  File "<pyshell#6>", line 2, in Sub
    foo = super().instance_method
RuntimeError: super(): no arguments

这在实例/类方法中才是真的!

答案 1 :(得分:4)

我可能错了,但你确定你不想要这个吗?

class A(object):
    def __init__(self):
        self.a = 1
        self.b = 2


class B(A):
    def __init__(self):
        super(B, self).__init__()
        self.c = 3

    @property
    def d(self):
        return self.a + self.b + self.c

BB = B()
print BB.d

或者,正如jonrsharpe指出的那样:

class A():
    a=1
    b=2

class B(A):
    c=3
    d=A.a+A.b+c

print B.d