继承:获取__init__的属性

时间:2014-03-04 04:52:38

标签: python inheritance

在以下示例中,a类或A内部类可以访问B中的C属性吗?

class A:

    def __init__(self, a):
        self.a = a

    def C_test(self):
        for i in range(4):
            c = self.C()

class C:
    print(self.a)


class B(A):

    def __init__(self):
        print(self.a)

为什么我会收到此错误?

Traceback (most recent call last):
  File "/Users/home/Desktop/Pygame/test.py", line 1, in <module>
    class A:
  File "/Users/home/Desktop/Pygame/test.py", line 10, in A
    class C:
  File "/Users/home/Desktop/Pygame/test.py", line 11, in C
    print(self.a)
NameError: name 'self' is not defined

3 个答案:

答案 0 :(得分:2)

self不是Python中的特殊变量名 - 它只是通常赋予方法的第一个参数的名称,该方法绑定到调用该方法的对象。

C类中的self.a没有出现在自我被列为参数的方法定义中,所以self在那里没有意义。

答案 1 :(得分:0)

如果从自己的基类派生类,则必须使用super调用基类的构造函数来继承基类属性:

class A(object):
    def __init__(self, a):
        self.a = a

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

执行此操作后,您可以执行以下操作:

a = A(1)
b = B()
b.a = a.a

b声明没有属性a,但是通过在B类中调用A via super的构造函数从A类继承它。 现在b.a评估1因为它被设置为a.a。

的值

答案 2 :(得分:0)

对于你的B例子,这个一般的想法确实有效,只是不自动。 Python在单一继承方面确实与Java有着大致相似的规则。它在这里不能自动运行的原因是因为Python的数据模型 - 成员变量附加到每个唯一的实例,而不是作为类的固有部分。正如在您的示例中,它们通常在__init__运行时附加到实例。因此,如果您的B有a,则需要A.__init__附加。如果你没有编写B.__init__,Python会自动为你运行,但是如果你有这个,你需要显式调用。最简单的方法是:

 class B(A):
     def __init__(self):
         super().__init__()

同样,您可能会认识到使用来自其他语言的超级明确链接的想法 - 虽然这里的拼写有点不同。但是Python和Java在这方面唯一的主要技术差异是Python需要为实例变量调用父构造函数甚至存在(在Java中,它们仍然存在,但可能没有正确的价值,甚至是初始化的。)

对于您的C示例,Python 非常与Java不同。 Python通常不使用术语“内部类”,尽管可以在另一个类中定义一个类(但请注意,您没有在代码示例中) - 但是内部类的实例不会与外部类的实例相关联。因此,它们的行为更像Java内部静态类。您可以通过执行以下操作明确地关联它们:

 class A:
     def __init__(self, a):
         self.a = a
         self.my_C = A.C(self)

     class C:
           def __init__(self, A_self):
               print(A_self.a)

但这并不常见,并且根据您的问题究竟是什么,几乎总有一种更好的方法来解决它,而不是试图将Java习惯用于Python代码。