I'm writing a small text game. I keep getting an error when trying to define a class variable.
Here's the class code:
class Scenery():
def __init__(self,name,description):
self.name=name
self.description=description
class Door(Scenery):
def __init__(self,openstatus,lockstatus):
self.openstatus=openstatus
self.lockstatus=lockstatus
super().__init__(name,description,openstatus,lockstatus)
class CageDoor(Door):
def __init__(self):
super().__init__(lockstatus=False,
openstatus=False,
name="Cage Door",
description="It's the door to the cage.")
The main.py code:
from tiles import CageDoor
CageDoor = CageDoor()
And the error:
File "main.py", line 3, in <module>
CageDoor = CageDoor()
*File Location*
name="Cage Door"
TypeError: __init__() got an unexpected keyword argument 'name'
When using super it is important that all the methods in the call chain use the same interface. Here you have Door
not taking name
, or description
. And Scenery doesn't take openstatus
or lockstatus
. You should have every method in the call chain accept *args
, and **kwargs
so it can ignore parameters it doesn't care about. For more information see this post
In this example it means re-writing Door
and Scenery
thusly:
class Scenery():
def __init__(self,name,description, *args, **kwargs):
self.name=name
self.description=description
class Door(Scenery):
def __init__(self openstatus,lockstatus, *args, **kwargs):
self.openstatus=openstatus
self.lockstatus=lockstatus
super().__init__(*args, **kwargs)
Door
's __init__
doesn't accept name
or description
, so the call in CageDoor.__init__
(which passes control to Door.__init__
because super()
determines that is the next class up in the inheritance hierarchy) is going to fail.
Change Door.__init__
to:
class Door(Scenery):
def __init__(self,openstatus,lockstatus, *args, **kwargs):
self.openstatus=openstatus
self.lockstatus=lockstatus
super().__init__(*args, **kwargs)
and it will then seamlessly pass along all arguments besides the two it uses to the next __init__
up the chain. The advantage to accepting and passing *args
and **kwargs
is that even if Scenery
's constructor prototype changes, Door
doesn't have to; the callers would need to pass along the correct arguments if no defaults are provided (so adding new arguments to Scenery
's constructor without giving them useful defaults is poor form), but Door
remains stable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With