从子类内的父类访问属性

Kar*_*rls 2 python inheritance class python-2.7

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

class A():
    a=1
    b=2

class B(A):
    c=3

d=B.a+B.b+B.c
print d
Run Code Online (Sandbox Code Playgroud)

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

class A():
    a=1
    b=2

class B(A):
    c=3
    d=a+b+c
    print d
Run Code Online (Sandbox Code Playgroud)

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

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

jon*_*rpe 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
Run Code Online (Sandbox Code Playgroud)

您甚至无法使用它们来访问它们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
Run Code Online (Sandbox Code Playgroud)

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

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


>>> Sub.foo is Super.class_attribute
True
Run Code Online (Sandbox Code Playgroud)

或者,您可以在类或实例方法中访问它们,但是您需要使用类(通常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
Run Code Online (Sandbox Code Playgroud)

这在实例/类方法中是唯一的!

  • 你称你的父类为“Super”这一事实让我感到非常困惑...... (2认同)

jak*_*e77 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
Run Code Online (Sandbox Code Playgroud)

或者,正如乔恩夏普指出的那样:

class A():
    a=1
    b=2

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

print B.d
Run Code Online (Sandbox Code Playgroud)