Reputation: 407
I'm working on a game, and one of the things I want to do is to have a base class that defines an attribute damage, and uses a constructor to initiate that value. This is my base class
class Weapon(object):
def __init__(self, damage):
self.damage = damage
This is the actual class that calls on Weapon for the game
class Crossbow(Weapon):
is_loaded = True
reloads = 5
def __init__(self, is_loaded, reloads):
super(Crossbow, self).__init__()
self.is_loaded = is_loaded
self.reloads = reloads
def reload(self):
print "You need to reload, before you can fire again"
time.sleep(2)
if reloads > 0:
print "Reloading bow"
time.sleep(2)
reloads -= 1
is_loaded = True
print "Successfully reloaded bow"
time.sleep(1)
print "You now have",reloads,"arrow left"
time.sleep(2)
else:
print "You don't have any more arrows"
time.sleep(2)
I was testing the reload function using:
c = Crossbow(Weapon)
for i in range(1,6):
c.reload()
The reason I run the class method 6 times, is that I wanted to test the reload variable which counts how many times you reload. It subtracts each time it counts, and once it reaches zero, it doesn't let you reload, so 6 times would be able to test the full functionality. However, when I run that block of code, I get this error:
me.py", line 47, in <module>
c = Crossbow(Weapon)
TypeError: __init__() takes exactly 3 arguments (2 given)
I've used classes before, but I'm new to creating a base class and constructor and calling other classes off of that. If someone could help me understand my problem, I would very much appreciate it.
Upvotes: 0
Views: 166
Reputation: 37319
When you specify a positional argument to your class's __init__
method, that means you're committing to passing in the arguments each time you instantiate the class. Because you've declared is_loaded
and reloads
as positional arguments to your Crossbow
class's __init__
method, you must provide them when instantiating. In your testing code, you're providing the class Weapon
as the value of your __init__
call's first positional paramater, is_loaded
. This is, of course, wrong, but not a syntax error. You're not providing any argument at all for reloads
, and that is a syntax error.
You may wish to set default values for the arguments which will be used if not provided, eg:
def __init__(self, is_loaded=True, reloads=5):
super(Crossbow, self).__init__(damage=5) # or whatever for damage
If you do that, you can instantiate without explicitly setting the values.
You could also set the default values to None and only override the class's values on a non-None value:
def __init__(self, is_loaded=None, reloads=None):
super(Crossbow, self).__init__(damage=5)
if is_loaded is not None:
self.is_loaded = is_loaded
if reloads is not None:
self.reloads = reloads
Upvotes: 1
Reputation: 280251
You create an instance of Crossbow with c = Crossbow(initial_load_state, initial_reloads)
, not c = Crossbow(Weapon)
. (Also, your superclass constructor call is missing a damage
argument.)
Upvotes: 0