Confused about behaviour of base class
This follows a question I asked a few hours ago.
I have this code:
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
This gives the error: AttributeError: 'B' object has no attribute 'a'
, as expected. I can fix this by calling super(B, self).__init__(a)
.
However, I have this code:
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)
Whose output is:
B called.
2
Why does this work? And more importantly, how does it work when I have not initialized the base class? Also, notice that it does not call the initializer of A
. Is it because when I do a:
def __init__(self, b, a)
I am declaring b
to be an attribute of B
? If yes, how can I check b
is an a开发者_如何学JAVAttribute of which class - the subclass or the superclass?
The way you defined it B
does not have any attributes. When you do print a
the a
refers to the local variable a
in the __init__
method, not to any attribute.
If you replace print a
with print self.a
you will get the same error message as before.
In your second code, calling print a
works because you are printing the variable passed as a parameter to B's __init__
function, not the self.a
variable (which is not initialized because A.__init__
was not called). Once you leave the scope of the __init__
function you will loose access to the a
.
The short answer is that __init__
isn't a constructor in the sense of other languages, like C++. It's really just a function that runs on an object after the "bare" object is created. B's __init__
function is conventionally responsible for calling A's __init__
, but it doesn't have to - if A.__init__
never gets called, then then A's attribute a
doesn't get added to the object, and so you get an error when you try to access it.
To fix this problem, you'll need to use
class B(A):
def __init__(self, b, a):
super(A, self).__init__(a)
Make sure you declare the classes as new style objects, something you're already doing
[edit: clarification]
精彩评论