在以下示例中,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
答案 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代码。