【问题标题】:Python import classes from modules dynamicallyPython 从模块中动态导入类
【发布时间】:2014-12-15 14:48:44
【问题描述】:

我正在使用一个包含许多子组件的 API。我正在制作一个工具包来与这个 API 进行交互,我想制作它以便我可以根据变量动态加载一些类,例如,加载所有内部设置了变量 api_module = True 的类。

.
├── APIModules
│   ├── ccu.py
│   ├── __init__.py
│   └── OpenAPI.py

ccu 文件中的 CCU 类

class CCU:
    api_module = True
    actions    = ['post_new_purge','get_purge_queue','get_purge_status']

这将帮助我在添加更多类时动态记录和扩展工具包,而无需在每次添加新子组件时维护导入列表。有没有简单的方法可以做到这一点?

我知道我可以使用 glob 获取 APIModules 目录中所有 python 文件的列表,但是我想加载并检查文件中的任何类,而不知道它们可能被调用什么。

import os
import glob
modules = glob.glob(os.path.dirname(__file__)+"/*.py")

【问题讨论】:

  • “加载”一个类是什么意思?您必须对其进行评估才能获得标志。
  • 我的意思是导入,但我想获取目录中所有文件中的所有类。我不介意他们都会被评估。

标签: python import dynamic-loading


【解决方案1】:

由于您需要导入类来读取其属性,并且您正在尝试确定是否应该首先导入它,所以这里有一个问题 22。

这为您提供了使用其他方法解析 .py 文件并根据该方法决定是否导入相关模块的方法。但是这种方法也很乱,也太复杂了。

我认为,最简单的方法是彻底改变观点。您可以在主应用程序中只包含一个活动模块列表,而不是在每个模块中都有api_module = True,然后根据它来决定:

api_modules = ["module_1", "module_2", "module_3"]

这减少了维护量(您只需维护一行代码)并提供相同的灵活性。

【讨论】:

  • 是的,我正在考虑这个问题——我现在就是这样。我只是想知道这是否可能
【解决方案2】:

您可以使用元类和类注册表来跟踪添加到系统中的任何新类。

这里有一个演练可以为您提供所需的帮助http://effbot.org/zone/metaclass-plugins.htm

这是否是一个好主意是另一个问题(我认为 sqlalchemy 将此模式用于声明性基础并且效果很好)。

# from http://effbot.org/zone/metaclass-plugins.htm
registry = [] # list of subclasses

class Plugin(object):
    class __metaclass__(type):
        def __init__(cls, name, bases, dict):
            type.__init__(name, bases, dict)
            registry.append((name, cls))

# in your plugin modules
class SpamPlugin(Plugin):
    pass

class BaconPlugin(Plugin):
    pass

# in your plugin loader
# import all plugin modules

# loop over registered plugins
for name, cls in registry:
    if cls is not Plugin:
        print name, cls
        # here you could check various attributes of the class to
        # see if it was one you wanted to use

编辑我想我有点误解了——你也不想一个一个地导入模块——但是你可以写一些东西来导入所有的文件api 文件夹。然后,每个类都将从维护注册表的 API 基类继承。当你想使用任何东西时,你可以去注册表找到你感兴趣的类。

【讨论】:

  • 这看起来很有希望
猜你喜欢
  • 1970-01-01
  • 2011-04-17
  • 2013-03-25
  • 1970-01-01
  • 2020-07-23
  • 2011-04-04
  • 1970-01-01
  • 2019-03-24
  • 2020-11-30
相关资源
最近更新 更多