В следующем фрагменте я пытаюсь определить фабричную функцию, которая будет возвращать объекты различных классов, полученных из Hero
на основе аргументов.
class Hero:
Stats = namedtuple('Stats', ['health', 'defence', 'attack',
'mana', 'experience'])
RaceMaxStats = OrderedDict([
('Knight', Stats(100, 170, 150, 0, inf)),
('Barbarian', Stats(120, 150, 180, 0, inf)),
('Sorceress', Stats(50, 42, 90, 200, inf)),
('Warlock', Stats(70, 50, 100, 180, inf))
])
@staticmethod
def def_race(race: str):
return type(race, (Hero,), {'max': Hero.RaceMaxStats[race]})
Races = OrderedDict([
(race, Hero.def_race(race)) for race in RaceMaxStats.keys()
])
def __init__(self, lord, health, defence, attack, mana, experience):
self.race = self.__class__.__name__
self.lord = lord
self.stats = Hero.Stats(min(health, self.max.health),
min(defence, self.max.defence),
min(attack, self.max.attack),
min(mana, self.max.mana),
min(experience, self.max.experience))
@staticmethod
def summon(race, *args, **kwargs):
return Hero.Races[race](*args, **kwargs)
С намерением позже использовать его так:
knight = Hero.summon('Knight', 'Ronald', 90, 150, 150, 0, 20)
warlock = Hero.summon('Warlock', 'Archibald', 50, 50, 100, 150, 50)
Проблема в том, что я не могу инициализировать подклассы, потому что Hero
еще не определено:
(race, Hero.def_race(race)) for race in RaceMaxStats.keys()
NameError: name 'Hero' is not defined
Очевидно, что если бы я заменил статический вызов метода прямым вызовом type()
, мне все равно потребовалось бы определить Hero
. Мой вопрос заключается в том, как лучше всего реализовать такую фабрику. Приоритет состоит в том, чтобы метод summon()
сохранял ту же сигнатуру и возвращал экземпляры классов, производных от Hero
.
P.S. ни один из приведенных выше кодов не был успешно выполнен, поэтому он может содержать другие ошибки.