对python来说非常陌生,它试图创建一个游戏,在这个游戏中可以创建任意数量的军队,但是每个军队都会预先呈现士兵的名字。
我想我需要使用super init来真正减少重复的代码,但是我一生都不知道如何使它工作据我所知,我的类Army应该是父类,其中RedArmyScout是子类。我只是在努力理解super().__init__()应该在哪里?

class Army:
    def __init__(self):
        self.color = None
        self.scoutname = None
        self.demomanname = None
        self.medicname = None

    def train_scout(self, weapon):
        return Scout(self.color, self.scoutname, weapon)

class RedArmy(Army):

    def __init__(self):
        self.color = "Red"
        self.scoutname = "Yankee"
        self.demomanname = "Irish"
        self.medicname = "Dutch"

class BlueArmy(Army):
    pass

class Scout:
    specialization = "fast captures"

    def __init__(self, color, scoutname, weapon):
        self.color = color
        self.scoutname = scoutname
        self.weapon = weapon

    def introduce(self):
        return (f'Hi I\'m {self.scoutname}, I do {self.specialization} and I wield a {self.weapon}')


my_army = RedArmy()
soldier_1 = my_army.train_scout("baseball bat")
print(soldier_1.introduce())

最佳答案

在哪里放置super().__init__(如果有)取决于类层次结构的具体情况。
最常见的情况是,如果你把它放在哪里很重要,你需要它在子类的__init__方法的一开始这将确保所有基类变量都已设置,其所有不变量都已满足,并且其所有方法都可以由子类__init__代码的其余部分调用。
在您的例子中,这很重要,因为您在基类和子类中设置了相同的属性。显然,您希望子类版本是采用的版本,因此它必须在默认分配之后,而不是之前:

class RedArmy(Army):
    def __init__(self):
        super().__init__()
        self.color = "Red"
        self.scoutname = "Yankee"
        self.demomanname = "Irish"
        self.medicname = "Dutch"

然而,值得考虑的是,您是否真的希望基类首先将这些变量设置为None
我假设在您的实际代码中,BlueArmy不只是要pass,而是要做与RedArmy相同的事情,用一些字符串替换所有这些值。
另外,代码的其余部分可能假定那里有有效的字符串,而不是None。像TypeError: '<' not supported between instances of 'NoneType' and 'str'这样的异常比AttributeError: 'GreenArmy' object has no attribute 'scoutname'更难调试,也不容易调试,所以为什么不干脆不使用默认值呢?然后,您可以完全消除Army.__init__,并且您不必首先担心在子类初始值设定项中调用super
或者,您可以让Army.__init__获取用于赋值的参数,并让子类调用super().__init__("Red", "Yankee", "Irish", "Dutch")。然后,Army()将引发一个TypeError而不是创建一个无效的Army实例或者您可以创建一个名为@abstractmethodself._setup()调用并期望每个子类提供,因此Army.__init__将引发一个关于实例化抽象类的更有意义的Army()。这些改进使得调试TypeError子类变得更加容易,如果您只有其中的两个子类,它们可能只是浪费时间,但是如果您有一堆子类,这些子类将由不同的人开发,或者经过很长的时间,可能是值得的。

10-08 08:32