Python 继承:获取_init的属性__
在下面的示例中,Python 继承:获取_init的属性__,python,inheritance,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)
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
回溯(最近一次呼叫最后一次):
文件“/Users/home/Desktop/Pygame/test.py”,第1行,在
A类:
文件“/Users/home/Desktop/Pygame/test.py”,第10行,在
C类:
文件“/Users/home/Desktop/Pygame/test.py”,第11行,C语言
打印(self.a)
NameError:未定义名称“self”
self
在Python中不是一个特殊的变量名-它只是一个通常指定给方法的第一个参数的名称,该参数绑定到调用该方法的对象
类C中的
self.a
不会出现在self作为参数列出的方法定义中,因此self在其中没有任何意义。如果从自己的基类派生类,则必须使用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中的super调用a的构造函数从类a继承它。
现在,b.a评估1,因为它被设置为a.a的值。对于b示例,这个一般想法确实有效,但不是自动的。Python确实在单继承方面,Python的规则与Java非常相似。它在这里不能自动工作的原因是Python的数据模型——成员变量附加到每个唯一的实例,而不是类的固有部分。在您的示例中,它们通常在运行
\uuuu init\uuu
时附加到实例。因此,要使您的B具有a
,它需要由a附加。如果您不编写B.\uuu init\uuuu
,Python将自动为您运行该函数,但如果您确实拥有该函数,则需要显式调用。最简单的方法是:
class B(A):
def __init__(self):
super().__init__()
同样,您可能会认识到使用其他语言的super显式链接的想法,尽管这里的拼写有点不同。但是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代码。那么C
如何访问a
?您需要一个a实例来访问它,因为a的每个实例都有一个不同的a
副本。例如,如果你有一个名为foo的A实例,你只需要通过foo.A
访问它。在B的开头调用A.。\uuuu init\uuuu。或者使用super。