super().__ init __()中的'意外的关键字参数'

时间:2015-12-16 23:41:03

标签: python python-3.x

我正在写一个小文字游戏。 在尝试定义类变量时,我一直收到错误。

这是类代码:

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'

2 个答案:

答案 0 :(得分:6)

Door&#39; __init__不接受namedescription,因此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没有namedescription。并且风景不会openstatuslockstatus。您应该让调用链中的每个方法都接受*args**kwargs,以便它可以忽略它不关心的参数。有关详细信息,请参阅this post

在此示例中,它意味着重新编写DoorScenery

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)