繁体   English   中英

Python从模块动态导入类

[英]Python import classes from modules dynamically

我正在使用具有许多子组件的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")

由于您需要导入该类以读取其属性,并且试图弄清楚是否应该首先导入它,因此这里有一个catch 22。

这样,您便可以使用其他方法来解析.py文件,并根据该方法决定是否导入相关模块。 但是这种方法也很混乱而且太复杂。

我认为,最简单的方法是彻底改变观点。 除了在每个模块内部都没有api_module = True ,您还可以在主应用程序内部只有一个活动模块列表,然后根据该列表进行决定:

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

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

您可以将元类与类注册表一起使用,以跟踪添加到系统中的任何新类。

这里有一个演练,应该为您提供所需的帮助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类继承。 当您想使用任何东西时,请转到注册表以查找您感兴趣的类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM