Error: "x instance has no attribute y" when trying to inherit from class
Solution 1
You overwrite the original __init__
, which is then never called and doesn't initialize the members. You must call the parent's __init__
separately, usually with this snippet:
def __init__(self):
super(Score, self).__init__()
See the docs for super()
for details. However, super()
only works for so-called new-style classes. You must therefore either change the definition of Play
to inherit from object
:
class Play(object)
or you call the parent's method directly:
def __init__(self):
Play.__init__(self)
Solution 2
When you inherit from the class Play
, you automatically get the attributes that you've created in the definition of Play
, but you don't get the attributes that you've created in Play.__init__
. You have to explicitly call it like so:
class Score(Play):
def __init__(self):
Play.__init__(self)
self.initialScore = 0
See Boldewyn's suggestion for using super
to do this; but IMO you should probably get used to the basic way inheritance works before fiddling with super
.
To further clarify, if you don't override __init__
as you have in this case, then it's inherited and called automatically.
Solution 3
You forgot to initialize the superclass.
class Score(Play):
def __init__(self):
super(Score, self).__init__()
self.initialScore = 0
Trufa
Existing code exerts a powerful influence. Its very presence argues that it is both correct and necessary.
Updated on June 05, 2022Comments
-
Trufa about 2 years
I can't really understand what I'm doing wrong, since when I try it in "small scale" and it is working there.
I have a class named
Play()
I goes like this:
class Play(): def __init__(self): file = open("/home/trufa/Desktop/test", "r") self.word = random.choice(file.readlines()).rstrip() self.errAllowed = 7 self.errMade = 0 self.errList = [] self.cheatsAllowed = 2##chetas not incrementing self.cheatsMade =0 self.wordList = ["*"]*len(self.word) ##this one is the one I want to have available in another class
...
Then I have another class called
Score()
class Score(Play): def __init__(self): self.initialScore = 0 def letterGuess(self): self.initialScore += 1 return self.errList
...
I instantiated both:
game = Play() points = Score()
And if I do:
print points.letterGuess()
It gives me an error:
Traceback (most recent call last): File "/home/trufa/workspace/hangpy/src/v2.py", line 188, in <module> startGame() File "/home/trufa/workspace/hangpy/src/v2.py", line 134, in startGame print points.letterGuess() File "/home/trufa/workspace/hangpy/src/v2.py", line 79, in letterGuess return self.errList AttributeError: Score instance has no attribute 'errList'
I don't understand why since I can do this without any trouble:
class One(): def __init__(self): self.list= [1,2] class Two(One): def meth(self): return self.list uan = One() tu = Two() print uan.list print tu.meth() ## Both output [1,2]
I'm very new to OOP so I could be doing all kinds of silly mistakes but I can't figure out where!
I think I have posted all the relevant code, but I you think the error might be elsewhere, I can provide it.
As I said I'm very new, so this might have nothing to do with inheritance I just think it called that when you get "something" from within another class (you must be shouting at the screen by now)
-
Trufa about 13 yearsThank you very much, I'm sure this is obvious, but you have to learn it at some point I guess :) +1 for first and correct answer!
-
senderle about 13 yearsTo further clarify, you must inherit from
object
in 2.x. In 3.x, old-style classes go away, so inheriting fromobject
is unnecessary. -
Boldewyn about 13 years@senderle: True, thanks. I should start to respect 3 more and not take it as given, that 2.x is used.
-
Trufa about 13 yearsI haven't yet understood how to use
super()
, wasn't this what you suggested. -
senderle about 13 years@Bolderwyn, I'm struggling to do that myself -- hence the comment. :)
-
Boldewyn about 13 years@Trufa: no, I made the same mistake, when I first started to use it. The first argument to super() is the own class, in the pastie example,
Two
. Think of it this way: super() returns the super-class of its first argument. -
Boldewyn about 13 yearsBy the way, in this way you can also call methods of super-super-classes all the way up the inheritance chain. If One inherits from Zero and isinstance(self, Two),
super(One, self).__init__
is the method of the class Zero. -
Trufa about 13 years@Boldewyn: No I'm even more confused! :) you say like this?
def __init__(self): super(Two, self).__init__()
(I say that what you suggest is in the docs, but I'm not figuring out somthing) -
senderle about 13 years@Trufa, I wrote a long comment that wound up reproducing what Bolderwyn has already said. So I'll just add that this is why I suggested getting used to inheritance before trying to use
super
. :) -
Boldewyn about 13 yearsRead this just the other minute via delicious: rhettinger.wordpress.com/2011/05/26/super-considered-super
-
Trufa about 13 years@senderle: I am actually using you method, but just trying to understand that for later. Thank for all the help!
-
Trufa about 13 years@Boldewyn: hmm ok but its not working that, way. I'm confused... I'll take another shot at it but I'll have @senderle 's advice in mind.