python | 动态导入模块import_module和重载reload
- 2022-04-20 10:00:00
- 上海悠悠
- 转贴:
- 公众号
- 3057
前言
python动态加载import_module 和 重载reload 的使用
python环境:V3.6.x
import_module
当我们在运行一段程序,根据需要动态加载一个模块,调用里面的方法时,除了平台使用的import module,也可以在代码里面用到import_module方法。
比如我有个模块 yoyo.py,里面写了个函数
def fun1(): return "hello world" def fun2(): return "上海-悠悠"
a.py 需要加载yoyo.py模块(2个文件在同一层级)
import importlib import inspect # 动态导入模块 m = importlib.import_module('yoyo') print(m) # module object # 调用fun1 print(m.fun1()) # hello world # 获取模块全部函数 items = inspect.getmembers(m, inspect.isfunction) print(dict(items)) # {'fun1': <function fun1 at 0x0000015CEAEA0DC0>, 'fun2': <function fun2 at 0x0000015CEAEEA670>}
运行结果:
<module 'yoyo' from 'D:\\demo\\demo\\yoyo.py'> hello world {'fun1': <function fun1 at 0x0000015CEAEA0DC0>, 'fun2': <function fun2 at 0x0000015CEAEEA670>}
动态更新模块
前面importlib.import_module()
导入模块是没有问题的,但是如果在执行的过程中 yoyo.py
模块发生了改变,会无法加载到最新的方法。
可以在python交互环境测试次问题
D:\demo\demo>python Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import importlib >>> m = importlib.import_module('yoyo') >>> m <module 'yoyo' from 'D:\\demo\\demo\\yoyo.py'> >>> m.fun1() 'hello world' >>> m.fun2() '上海-悠悠' >>>
当我在yoyo.py模块新增一个fun3()函数时,yoyo.py内容如下
def fun1(): return "hello world" def fun2(): return "上海-悠悠" def fun3(): return "hello yoyo"
此时继续在上面交互环境操作,调用fun3()方法
>>> m.fun3() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'yoyo' has no attribute 'fun3' >>>
于是会看到新增的函数是无法调用的,因为在前面已经导入了模块,模块里面的2个函数,已经被加载进去了,后面模块更新的内容是不会自动更新的。
那么有没什么办法,可以在新增方法后,重新让系统加载一次模块呢?这里可以用到reload() 方法,重载模块
reload() 重载模块
接着刚才的报错,使用reload()重载模块
>>> from importlib import reload >>> new = reload('yoyo') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "E:\python36\lib\importlib\__init__.py", line 139, in reload raise TypeError("reload() argument must be a module") TypeError: reload() argument must be a module >>>
直接写模块名称会出现报错:reload() argument must be a module
看下reload()的相关源码说明:传的module参数必须在使用之前被成功导入过。
def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ if not module or not isinstance(module, types.ModuleType): raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: name = module.__name__
module参数可以通过sys模块获取到模块对象 sys.modules['yoyo']
>>> import sys >>> sys.modules['yoyo'] <module 'yoyo' from 'D:\\demo\\demo\\yoyo.py'> >>> new = importlib.reload(sys.modules['yoyo']) >>> new.fun3() 'hello yoyo' >>> new.fun1() 'hello world' >>> new.fun2() '上海-悠悠'
于是就可以成功调用到新增的fun3()方法
更新方法和删除方法
如果更新了方法里面代码,fun3()改成返回”123456”
def fun3(): return "123456"
重新reload()后,代码也会更新
>>> new = importlib.reload(sys.modules['yoyo']) >>> new.fun3() '123456'
如果把func3()删除了呢?
>>> new = importlib.reload(sys.modules['yoyo']) >>> new.fun3() '123456'
重新reload()后,依然可以调用到fun3()函数,被删除的方法不会剔除。
发表评论
联系我们
- 联系人:阿道
- 联系方式:17762006160
- 地址:青岛市黄岛区长江西路118号青铁广场18楼