Python的新手,试图创建一个可以创建任意数量的军队的游戏,但每支军队都会预先渲染士兵的姓名。
我认为我需要使用super init来真正减少重复的代码,但是我一生都无法弄清楚如何使其工作。据我了解,我的班级DELIMITER $$
CREATE DEFINER=`mjrinker`@`localhost` PROCEDURE `rand_id`(IN `min` BIGINT, IN `max` BIGINT, IN `tablename` VARCHAR(128) CHARSET utf8, OUT `uid` BIGINT)
BEGIN
SET @count_id = 1;
SET uid = 0;
SET @s = CONCAT('SELECT COUNT(`id`) INTO @count_id FROM `', tablename, '` WHERE `id` = ?');
PREPARE stmt from @s;
WHILE @count_id > 0 DO
SET @uid = FLOOR(rand() * max + min);
EXECUTE stmt USING @uid;
END WHILE;
DEALLOCATE PREPARE stmt;
SET uid = @uid;
END$$
DELIMITER ;
应该是父级班级,Army
和RedArmy
是子类。我只是在努力了解Scout
应该放在哪里?
super().__init__()
答案 0 :(得分:5)
放置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
实例。或者,您可以创建一个名为@abstractmethod
的{{1}}并self._setup()
调用并期望每个子类提供,因此Army.__init__
会引发关于实例化一个更有意义的Army()
的信息。抽象类。这些改进使调试TypeError
子类变得更容易-如果您只有两个子类,它们可能只是浪费时间,但是如果您有很多子类,那么这些子类将由不同的人开发还是很长一段时间,这可能是值得的。
答案 1 :(得分:-1)
如果要让类利用super
和init
的话,将值作为参数传递是最有意义的:
class Army:
def __init__(self, color=None, scoutname=None, demomanname=None,
medicname=None):
self.color = color
self.scoutname = scoutname
self.demomanname = demomanname
self.medicname = medicname
def train_scout(self, weapon):
return Scout(self.color, self.scoutname, weapon)
class RedArmy(Army):
def __init__(self, color="Red", scoutname="Yankee", demomanname="Irish",
medicname="Dutch"):
super().__init__(color, scoutname, demomanname, medicname)
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 '
f'a {self.weapon}')
my_army = RedArmy()
soldier_1 = my_army.train_scout("baseball bat")
print(soldier_1.introduce())