标准库importlib
内置getattr
内置dir
这几个可以帮助你实现想要的需求,这也是项目当中lazyImport很常见的一种方式。
题主可以自己先根据文档尝试怎么写,有空我再写具体怎么实现
不太清楚你的具体需求是什么,我就说说整体思路和贴一些参考代码仅供参考,如有疑惑或者我说错的地方,欢迎讨论。
首先第一步是利用importlib实例化包/模块,参数具体使用请参考文档
经过importlib实例化以后生成了包/模块对象,此时如果调用该对象,是已经能够获取到对象的所包含的方法/类的(特殊情况除外,后面讨论)。
此时我们可以通过内置dir获取该对象的所包含的所有属性名称列表
获取到属性名称列表以后就可以利用内置getattr方法了
遍历属性列表,通过getattr获取该对象的属性实例了
至于如果判断是否为我们所需要的属性,这个就看你的需求了,如果是只需要该对象当中的函数属性,那么可以通过inspect.isfunction(attr)来判断是否为函数,如果只需要类,那么可以通过isinstance(attr, type)来判断该属性是否为类
贴上我的项目中的__init__文件的部分代码,我是用的是python2,大体看python3也可以兼容
# coding=utf8
# !/usr/bin/python2.7
import importlib
import os
import sys
from os.path import dirname, join
sys.path.append(dirname(__file__))
sys.path.append(dirname(dirname(__file__)))
sys.path.append(join(dirname(dirname(dirname(__file__))), 'Config'))
for m in [f[:-3] for f in os.listdir(dirname(__file__)) if f.endswith('py') and f != '__init__.py']:
module = importlib.import_module(m)
clses = [getattr(module, x) for x in dir(module) if isinstance(getattr(module, x), type)]
for cls in clses:
setattr(sys.modules[__name__], cls.__name__, cls)
另一个项目中用到的方式,在A工具包当中导入了Config工具包对象(A和Config同级),因为在这个项目中我有使用到一些相对导入(类似from . import toolkit),出现了无法获取到该模块对象属性的情况,需要在_init_文件中添加该模块的属性对象。
例如我的Config模块下存在名为TreeManager管理模块,但是在此时我通过Config.TreeManager是无法调用的,只能在Config模块下的__init__文件当中添加一句from . import TreeManager,这应该与importlib导入层次有关,importlib只能导入两层结构(这里我也比较疑惑为什么必须在init文件当中添加,import也是个大话题,python有专门的PEP讲解)
import importlib
Config = importlib.import_module("Config", "../Config")