我工作的一个基于文本的冒险游戏,并拥有一个具有所有的动作类,例如模块Move(Action)
,Look(Action)
。我需要一种将模块中作为类的子类的所有类实例Action
化为这样的列表的方法:
actions = [Move(), Look()]
有没有一种方法,而不必通过键入类的名称来单独实例化类?
这有效:
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()
返回一个dictview对象,该对象反映了底层字典中的更改。由于我们在同一模块中工作,因此定义新对象将更改此字典。转换为列表可以解决此问题。
接下来,我们遍历所有对象。要满足以下条件,必须满足三个条件Action
:
obj is not Action
-由于Action
是自身的子类,因此需要将其过滤掉。
isinstance(obj, type)
-对象必须是一个类。否则,将无法进行3.下的测试。
issubclass(obj, Action)
-最后,我们可以进行子类测试。
现在,我们可以创建所有过滤的类的实例,并将它们附加到列表中:
actions.append(obj())
如果您确定所有类都在一个模块中定义,或者甚至希望所有子类都分布在多个模块中,则这会短得多:
>>> actions = [obj() for obj in Action.__subclasses__()]
>>> actions
[<__main__.Move at 0x10fc14fd0>, <__main__.Look at 0x10fc14668>]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句