题外话

很多Python源码中,会有一句if __name__ == '__main__':,其中__name__为python的一个内置类属性,存在于每一个python程序中,不同运行方式会出现不同的结果。

  1. 直接运行当前程序,文件中的__name__的值为“__main__”。
  2. 其他程序导入当前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(namepackage=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)

      

        

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐