Python实例化模块中的所有类

时间:2016-01-01 09:03:26

标签: python python-3.5 adventure

我正在开发基于文本的冒险游戏,并且拥有一个包含所有动作类的模块,例如: <?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password', 60); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } } Move(Action)。我需要一种方法,将模块中作为Look(Action)类的子类的所有类实例化为如下列表:

Action

有没有办法这样做而无需通过输入名称来单独实例化类?

2 个答案:

答案 0 :(得分:7)

解决方案

这有效:

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的子类:

  1. obj is not Action - 由于Action是其自身的子类,我们需要将其过滤掉。

  2. isinstance(obj, type) - 对象必须是一个类。否则,3下的测试是不可能的。

  3. issubclass(obj, Action) - 最后,我们可以进行子类测试。

  4. 现在我们可以创建所有过滤类的实例并将它们附加到我们的列表中:

    actions.append(obj())
    

    较短版本

    如果您确定所有类都在一个模块中定义,或者您甚至希望所有子类分布在多个模块上,那么这将更短:

    >>> actions = [obj() for obj in Action.__subclasses__()]
    >>> actions
    [<__main__.Move at 0x10fc14fd0>, <__main__.Look at 0x10fc14668>]
    

答案 1 :(得分:1)

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]