python笔记73-动态导入模块import_module 和 重载reload

前言

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()函数,被删除的方法不会剔除。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果您已经在编译 Nginx 时包含了 `--with-http_ssl_module` 参数,但是在使用 `ssl` 参数时仍然出现错误,可能是因为您在 Nginx 的配置文件中有多个 `http` 块,而您只在其中一个 `http` 块中加载了 `ngx_http_ssl_module` 模块。 要解决此问题,您可以使用以下步骤: 1. 确定哪个 `http` 块中包含了 `ngx_http_ssl_module` 模块 在终端中输入以下命令: ``` sudo nginx -t ``` 这将检查您的 Nginx 配置文件中的语法错误。如果您只有一个 `http` 块,则跳过此步骤。 否则,请检查输出以找到哪个 `http` 块中包含了 `ngx_http_ssl_module` 模块。在输出中,应该看到类似于以下内容的行: ``` nginx: configuration file /etc/nginx/nginx.conf test is successful ``` 请注意,这里的 `/etc/nginx/nginx.conf` 可能与您的配置文件路径不同。 2. 将 `ngx_http_ssl_module` 模块加载到所有 `http` 块中 在 Nginx 的配置文件中,您应该确保在所有 `http` 块中加载了 `ngx_http_ssl_module` 模块。例如: ``` http { # 加载 ngx_http_ssl_module 模块 ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA; ssl_certificate /path/to/ssl_certificate; ssl_certificate_key /path/to/ssl_certificate_key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # 其他配置 } http { # 加载 ngx_http_ssl_module 模块 ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA; ssl_certificate /path/to/ssl_certificate; ssl_certificate_key /path/to/ssl_certificate_key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # 其他配置 } ``` 请注意,所有 `http` 块都应该包含 `ngx_http_ssl_module` 模块的加载。 3. 重新加载 Nginx 配置 在更改 Nginx 配置文件后,需要重新加载 Nginx 配置以使更改生效。您可以使用以下命令重新加载 Nginx 配置: ``` sudo nginx -t && sudo nginx -s reload ``` 现在,您的 Nginx 配置文件应该已经正确加载了 `ngx_http_ssl_module` 模块,并且您应该能够在配置文件中使用 `ssl` 参数了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值