Python从模块动态导入类

2024-04-18 22:39:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用一个有许多子组件的API。我正在制作一个工具箱来与这个API交互,我想制作它,这样我就可以基于变量动态地加载一些类,例如,加载所有内部设置了变量API_module=True的类。在

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

CCU文件中的CCU类

^{pr2}$

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

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

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

Tags: 文件pyimportapitrue列表os组件
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类继承。当你想处理任何东西时,你可以去注册中心找到你感兴趣的类。在

因为您需要导入类来读取它的属性,并且您正试图确定是否应该首先导入它,所以这里有一个catch 22。在

这样就可以使用其他方法解析.py文件,并基于此决定是否导入有问题的模块。但这种方法也很混乱,而且过于复杂。在

我认为,最简单的方法就是彻底改变观点。与在每个模块中都有api_module = True不同的是,您只需在主应用程序中有一个活动模块的列表,并据此决定:

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

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

相关问题 更多 >