Python: 在class body中动态创建一个subclass
Python: create a subclass dynamically in class body
在下面的代码片段中,我试图定义一个工厂函数,它将 return 不同 类 的对象根据参数派生自 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)
问题是我无法初始化 sub类 因为 Hero
还没有定义:
(race, Hero.def_race(race)) for race in RaceMaxStats.keys()
NameError: name 'Hero' is not defined
显然,如果我用直接 type()
调用替换静态方法调用,我仍然需要定义 Hero
。我的问题是如何最好地实施这种工厂。 summon()
方法的优先级是保留相同的签名,以及从 Hero
.
派生的 类 的 return 个实例
P.S。上面的代码none曾经运行成功过,所以可能还有其他错误。
在class定义之后,做Hero.knight = Hero.summon(...)
等等。
您可以使用 classmethods 并将您的 Races
变量定义为一种方法,该方法在首次调用 class 变量后缓存其结果。它看起来像这样:
@classmethod
def def_race(cls, race: str):
return type(race, (cls,), {'max': cls.RaceMaxStats[race]})
_Races = None
@classmethod
def Races(cls, race):
if cls._Races is None:
cls._Races = OrderedDict([
(race, cls.def_race(race)) for race in cls.RaceMaxStats.keys()
])
return cls._Races[race]
@classmethod
def summon(cls, race, *args, **kwargs):
return cls.Races(race)(*args, **kwargs)
你能试试吗:
Hero('Knight', 'Ronald', 90, 150, 150, 0, 20).summon()
或者:
hero = Hero('Knight', 'Ronald', 90, 150, 150, 0, 20)
hero.summon()
在下面的代码片段中,我试图定义一个工厂函数,它将 return 不同 类 的对象根据参数派生自 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)
问题是我无法初始化 sub类 因为 Hero
还没有定义:
(race, Hero.def_race(race)) for race in RaceMaxStats.keys()
NameError: name 'Hero' is not defined
显然,如果我用直接 type()
调用替换静态方法调用,我仍然需要定义 Hero
。我的问题是如何最好地实施这种工厂。 summon()
方法的优先级是保留相同的签名,以及从 Hero
.
P.S。上面的代码none曾经运行成功过,所以可能还有其他错误。
在class定义之后,做Hero.knight = Hero.summon(...)
等等。
您可以使用 classmethods 并将您的 Races
变量定义为一种方法,该方法在首次调用 class 变量后缓存其结果。它看起来像这样:
@classmethod
def def_race(cls, race: str):
return type(race, (cls,), {'max': cls.RaceMaxStats[race]})
_Races = None
@classmethod
def Races(cls, race):
if cls._Races is None:
cls._Races = OrderedDict([
(race, cls.def_race(race)) for race in cls.RaceMaxStats.keys()
])
return cls._Races[race]
@classmethod
def summon(cls, race, *args, **kwargs):
return cls.Races(race)(*args, **kwargs)
你能试试吗:
Hero('Knight', 'Ronald', 90, 150, 150, 0, 20).summon()
或者:
hero = Hero('Knight', 'Ronald', 90, 150, 150, 0, 20)
hero.summon()