class 什么时候可以保证子class?
When does a class warrant a sub-class?
例如,我正在尝试为一个简单的游戏构建一个敌人 class。每个生成的 enemy 都有一个 type 会影响它的统计信息,这些字段是 enemy class.
class Enemy:
#Base Stats for all enemies
name = "foo"
current_health = 4
max_health = 4
attack = 0
defense = 0
armor = 0
initiative = 0
initMod = 0
alive = True
每个 type 是否应该像这样成为 enemy 的 subclass ..
class goblin(Enemy):
name = goblin;
current_health = 8
max_health = 8
attack = 3
defense = 2
armor = 0
def attack(){
//goblin-specific attack
}
但是这种方法意味着我必须为每个 type 构建一个 class(这将是 80+ classes),或者有更好的方法吗?这个 enemy 将被随机化,所以我在想 types 也可以放入 dictionary,它使用 类型 的名称作为关键字。虽然我不完全确定如何实现它。
如果你想走字典路线,你可以用键返回的元组做这样的事情:
enemy_types = {"goblin": ("goblin", 8, 8, 3, 2, 0, goblin_attack)}
def goblin_attack(enemy):
do_stuff()
尽管您可能想使用 named_tuple
确保您不会混淆元组中的字段
如果每种敌人类型的属性集和可能的操作在不同类型中几乎是通用的,我认为没有理由做比为该类型定义 80 项枚举并使用单个 class 称为 Enemy
.
如果您确实需要各种操作等,也许您可以将 80 种类型分组到各种集合中,这些集合将具有共同的属性(例如 FlyingEnemy
、UndeadEnemy
等)。那些将成为你的子classes。
妖精应该是 Enemy 的一个实例。但是,在您的示例中,您添加了一个名为 attack
的方法。我想说最好的方法是这样的:
class Enemy:
#Base Stats for all enemies
def __init__ (self, **kwargs):
self.name = "foo"
self.current_health = 4
self.max_health = 4
self.attack = 0
self.defense = 0
self.armor = 0
self.initiative = 0
self.initMod = 0
self.alive = True
# Use this to specify any other parameters you may need
for key in kwargs:
exec ("self.%s = %s" % (key, kwargs[key])
现在您可以创建一个名为 goblin 的 Enemy
实例。
为了回答您关于何时使用子类的最初问题,我会说使用 sub-类 很好,但在您的情况下可能会使事情变得过于复杂。由于您的子类中只有一个方法,您可以轻松地创建一个模块,然后在 __init__
中有一个参数指定 attack
函数。这将进一步简化您的代码。
Note: If you are going to use subclasses make sure that in the __init__
of your subclass you call the __init__
of your baseclass with super()
.
例如,我正在尝试为一个简单的游戏构建一个敌人 class。每个生成的 enemy 都有一个 type 会影响它的统计信息,这些字段是 enemy class.
class Enemy:
#Base Stats for all enemies
name = "foo"
current_health = 4
max_health = 4
attack = 0
defense = 0
armor = 0
initiative = 0
initMod = 0
alive = True
每个 type 是否应该像这样成为 enemy 的 subclass ..
class goblin(Enemy):
name = goblin;
current_health = 8
max_health = 8
attack = 3
defense = 2
armor = 0
def attack(){
//goblin-specific attack
}
但是这种方法意味着我必须为每个 type 构建一个 class(这将是 80+ classes),或者有更好的方法吗?这个 enemy 将被随机化,所以我在想 types 也可以放入 dictionary,它使用 类型 的名称作为关键字。虽然我不完全确定如何实现它。
如果你想走字典路线,你可以用键返回的元组做这样的事情:
enemy_types = {"goblin": ("goblin", 8, 8, 3, 2, 0, goblin_attack)}
def goblin_attack(enemy):
do_stuff()
尽管您可能想使用 named_tuple
确保您不会混淆元组中的字段
如果每种敌人类型的属性集和可能的操作在不同类型中几乎是通用的,我认为没有理由做比为该类型定义 80 项枚举并使用单个 class 称为 Enemy
.
如果您确实需要各种操作等,也许您可以将 80 种类型分组到各种集合中,这些集合将具有共同的属性(例如 FlyingEnemy
、UndeadEnemy
等)。那些将成为你的子classes。
妖精应该是 Enemy 的一个实例。但是,在您的示例中,您添加了一个名为 attack
的方法。我想说最好的方法是这样的:
class Enemy:
#Base Stats for all enemies
def __init__ (self, **kwargs):
self.name = "foo"
self.current_health = 4
self.max_health = 4
self.attack = 0
self.defense = 0
self.armor = 0
self.initiative = 0
self.initMod = 0
self.alive = True
# Use this to specify any other parameters you may need
for key in kwargs:
exec ("self.%s = %s" % (key, kwargs[key])
现在您可以创建一个名为 goblin 的 Enemy
实例。
为了回答您关于何时使用子类的最初问题,我会说使用 sub-类 很好,但在您的情况下可能会使事情变得过于复杂。由于您的子类中只有一个方法,您可以轻松地创建一个模块,然后在 __init__
中有一个参数指定 attack
函数。这将进一步简化您的代码。
Note: If you are going to use subclasses make sure that in the
__init__
of your subclass you call the__init__
of your baseclass withsuper()
.