python importlib详解
题外话很多Python源码中,会有一句if __name__ == '__main__':,其中__name__为python的一个内置类属性,存在于每一个python程序中,不同运行方式会出现不同的结果。直接运行当前程序,文件中的__name__的值为“__main__”。其他程序导入当前python程序,原文件中__name__的值为“原文件的名字”。python的importlib模块作用动
·
题外话
很多Python源码中,会有一句if __name__ == '__main__':,其中__name__为python的一个内置类属性,存在于每一个python程序中,不同运行方式会出现不同的结果。
直接运行当前程序,文件中的__name__的值为“__main__”。
其他程序导入当前python程序,原文件中__name__的值为“原文件的名字”。
python的importlib模块
作用
动态导入需要的python程序文件的module,module可以用调用该模块下的所有属性和方法。
可从下面两个方面探讨:
- module动态导入
- 检查模块是否可以导入
module动态导入
文件结构
a #文件夹
│a.py
│__init__.py
b #文件夹
│b.py
│__init__.py
├─c#文件夹
│c.py
│__init__.py
# c.py 中内容
args = {'a':1}
class C:
def c(self):
pass
当需要在a.py文件中调用c.py文件中的对象/方法时,可采用importlib.import_module函数
#a.py
首先看一下importlib.import_module(name, package=None)函数的参数
函数调用存在两种方式:
1.绝对导入,name为完整路径str,package为None。
2.相对导入,package需指定对应包位置。
import importlib
#绝对导入
params = importlib.import_module('b.c.c')
#相对导入,注意路径前面有一个“.”,(这时__name__就可以派上用场)
params_ = importlib.import_module('.c.c',package='b')
# 对象中取出需要的对象
params.args #取出变量
params.C #取出class C
params.C.c #取出class C 中的c 方法
检查模块是否可以导入
并不是所有模块都可以成功导入,这时候可采用importlib.util.find_spec函数来判断查找的module是否存在。官方该函数的具体解析如下:
importlib.util.
find_spec
(name, package=None)
- 3.4 新版功能. 查找模块的 spec,相对指定的 package 名为可选参数。如果该模块位于 sys.modules 中,则会返回
sys.modules[name].__spec__
(除非 spec为None
或未作设置,这时会触发 ValueError)。否则将用 sys.meta_path 进行搜索。若找不到则返回None
。 如果 name 为一个子模块(带有一个句点),则会自动导入父级模块。name 和 package 的用法与import_module()
相同。 - 在 3.7 版更改: 如果 package 实际上不是一个包(即缺少 __path__ 属性)则会引发 ModuleNotFoundError 而不是 AttributeError。
可以发现在新版本中,importlib.util.find_spec在找不到模块的时候已经不返回None,而是直接引发
ModuleNotFoundError异常了,这个需要注意一下。(当前测试过程中,如果父级目录不存在会报异常,若只有根目录不存在则返回None)
更多推荐
已为社区贡献4条内容
所有评论(0)