这是我几个小时前提出的一个问题。
我有这段代码:
class A(object):
def __init__(self, a):
print 'A called.'
self.a = a
class B(A):
def __init__(self, b, a):
print 'B called.'
x = B(1, 2)
print x.a
这会产生错误:AttributeError: 'B' object has no attribute 'a'
,如预期的那样。我可以通过致电super(B, self).__init__(a)
来解决这个问题。
但是,我有这段代码:
class A(object):
def __init__(self, a):
print 'A called.'
self.a = a
class B(A):
def __init__(self, b, a):
print 'B called.'
print a
x = B(1, 2)
谁的输出是:
B called.
2
为什么这样做?更重要的是,当我没有初始化基类时,它是如何工作的?另请注意,它不会调用A
的初始值设定项。是因为当我做的时候:
def __init__(self, b, a)
我声明b
是B
的属性?如果是,我如何检查b
是哪个类的属性 - 子类还是超类?
答案 0 :(得分:4)
您定义它的方式B
没有任何属性。执行print a
后,a
会引用a
方法中的本地变量__init__
,而不是任何属性。
如果您将print a
替换为print self.a
,您将收到与以前相同的错误消息。
答案 1 :(得分:2)
在第二个代码中,调用print a
是有效的,因为您将作为参数传递的变量打印到B的__init__
函数,而不是self.a
变量(由于{{未初始化) 1}}没有被调用)。一旦离开A.__init__
函数的范围,您将无法访问__init__
。
答案 2 :(得分:1)
简短的回答是__init__
不是其他语言(如C ++)意义上的构造函数。它实际上只是在创建“裸”对象后在对象上运行的函数。 B的__init__
函数通常负责调用A的__init__
,但它不必 - 如果A.__init__
永远不会被调用,那么A的属性a
就不会被调用添加到对象中,因此当您尝试访问它时会出现错误。
答案 3 :(得分:1)
要解决此问题,您需要使用
class B(A):
def __init__(self, b, a):
super(A, self).__init__(a)
确保将类声明为新样式对象,这是您已经在做的事情
[编辑:澄清]