Python 实例化模块中的所有 类
Python Instantiate All Classes Within a Module
我正在开发一款基于文本的冒险游戏,并且有一个包含所有动作的模块 classes,例如Move(Action)
、Look(Action)
。我需要一种方法来实例化模块中作为 Action
class 的子 class 的所有 classes 到这样的列表中:
actions = [Move(), Look()]
有没有一种方法可以做到这一点,而不必通过键入它们的名称来单独实例化 classes?
from other_module import Action
def is_action_class(var):
return var != Action and type(var) == type and issubclass(var, Action)
classes = []
for attr in dir(my_module):
var = getattr(my_module, attr)
if is_action_class(var):
classes.append(var)
instances = [c() for c in classes]
解决方案
这个有效:
class Action:
pass
class Move(Action):
pass
class Look(Action):
pass
actions = []
global_objs = list(globals().items())
for name, obj in global_objs:
if obj is not Action and isinstance(obj, type) and issubclass(obj, Action):
actions.append(obj())
print(actions)
打印:
[<__main__.Move object at 0x101916ba8>, <__main__.Look object at 0x101916be0>]
步骤
首先,我们获取当前模块中所有对象的名称:
global_objs = list(globals().items())
我们需要转换成列表,因为在Python 3 items()
return中有一个反映底层字典变化的dictview对象。由于我们在同一个模块中工作,定义新对象将更改此字典。转换成列表解决了这个问题。
接下来,我们遍历所有对象。他们需要满足三个条件才能成为 Action
的 subclass:
obj is not Action
- 由于Action
本身是子class,我们需要过滤掉它。
isinstance(obj, type)
- 对象必须是 class。否则,无法进行 3. 下的测试。
issubclass(obj, Action)
- 最后,我们可以进行子class测试。
现在我们可以创建所有过滤的 classes 的实例并将它们附加到我们的列表中:
actions.append(obj())
较短的版本
如果您确定所有 class 都在一个模块中定义,或者您甚至希望所有子 class 分布在多个模块中,那么这会更短:
>>> actions = [obj() for obj in Action.__subclasses__()]
>>> actions
[<__main__.Move at 0x10fc14fd0>, <__main__.Look at 0x10fc14668>]
我正在开发一款基于文本的冒险游戏,并且有一个包含所有动作的模块 classes,例如Move(Action)
、Look(Action)
。我需要一种方法来实例化模块中作为 Action
class 的子 class 的所有 classes 到这样的列表中:
actions = [Move(), Look()]
有没有一种方法可以做到这一点,而不必通过键入它们的名称来单独实例化 classes?
from other_module import Action
def is_action_class(var):
return var != Action and type(var) == type and issubclass(var, Action)
classes = []
for attr in dir(my_module):
var = getattr(my_module, attr)
if is_action_class(var):
classes.append(var)
instances = [c() for c in classes]
解决方案
这个有效:
class Action:
pass
class Move(Action):
pass
class Look(Action):
pass
actions = []
global_objs = list(globals().items())
for name, obj in global_objs:
if obj is not Action and isinstance(obj, type) and issubclass(obj, Action):
actions.append(obj())
print(actions)
打印:
[<__main__.Move object at 0x101916ba8>, <__main__.Look object at 0x101916be0>]
步骤
首先,我们获取当前模块中所有对象的名称:
global_objs = list(globals().items())
我们需要转换成列表,因为在Python 3 items()
return中有一个反映底层字典变化的dictview对象。由于我们在同一个模块中工作,定义新对象将更改此字典。转换成列表解决了这个问题。
接下来,我们遍历所有对象。他们需要满足三个条件才能成为 Action
的 subclass:
obj is not Action
- 由于Action
本身是子class,我们需要过滤掉它。isinstance(obj, type)
- 对象必须是 class。否则,无法进行 3. 下的测试。issubclass(obj, Action)
- 最后,我们可以进行子class测试。
现在我们可以创建所有过滤的 classes 的实例并将它们附加到我们的列表中:
actions.append(obj())
较短的版本
如果您确定所有 class 都在一个模块中定义,或者您甚至希望所有子 class 分布在多个模块中,那么这会更短:
>>> actions = [obj() for obj in Action.__subclasses__()]
>>> actions
[<__main__.Move at 0x10fc14fd0>, <__main__.Look at 0x10fc14668>]