我正在写一个小文字游戏。 在尝试定义类变量时,我一直收到错误。
这是类代码:
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.")
main.py代码:
from tiles import CageDoor
CageDoor = CageDoor()
错误:
File "main.py", line 3, in <module>
CageDoor = CageDoor()
*File Location*
name="Cage Door"
TypeError: __init__() got an unexpected keyword argument 'name'
答案 0 :(得分:6)
Door
&#39; __init__
不接受name
或description
,因此CageDoor.__init__
中的呼叫(将控制权转移到Door.__init__
因为super()
确定继承层次结构中的下一个类将会失败。
将Door.__init__
更改为:
class Door(Scenery):
def __init__(self,openstatus,lockstatus, *args, **kwargs):
self.openstatus=openstatus
self.lockstatus=lockstatus
super().__init__(*args, **kwargs)
然后它会将除了它使用的两个参数之外的所有参数无缝传递到链上的下一个__init__
。接受和传递*args
和**kwargs
的好处是,即使Scenery
的构造函数原型发生了变化,Door
也不必;如果没有提供默认值,调用者将需要传递正确的参数(因此向Scenery
的构造函数添加新参数而不给它们有用的默认值是不好的形式),但Door
保持稳定
答案 1 :(得分:1)
使用super时,调用链中的所有方法都使用相同的接口非常重要。在这里,您Door
没有name
或description
。并且风景不会openstatus
或lockstatus
。您应该让调用链中的每个方法都接受*args
和**kwargs
,以便它可以忽略它不关心的参数。有关详细信息,请参阅this post
在此示例中,它意味着重新编写Door
和Scenery
:
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)