我又来分享开源模块了,项目名是pyautoreload,这是前段时间写后端服务时用到的模块,我现在独立插取成一个项目,开源出来,希望这模块对大家有些用处…


关于python各种方法导入模块的介绍,如何reload重新加载类及函数原文地址是:

http://xiaorui.cc  http://xiaorui.cc/?p=2065


pyautoreload这名字,一看就知道是干嘛的? 对的,他确实是个动态导入模块,并重新加载的模块的模块,有点绕口…

一说载入模块,大家肯定会首先想到的是平时常用的import xx , from xiaorui.cc import view 这样的用法,但是这种用法适合咱们python程序一开始加载,绝大数的场景都是一开头就加载需要的模块.

首先我们做个测试:


我这里会用到__import__,他的功能跟importlib是一样的。 都可以把字符串形式的模块导入到python环境里面。虽然跟同import语句同样的功能,但__import__和importlib是函数,并且只接收字符串作为参数,所以它的作用你也就懂了,比如celery rq这样的工作任务队列,就会有这种动态加载模块的需求….

看了下python文档,发现import语句底层也是__import__ 


__import__的详细用法.
__import__(module_name[, globals[, locals[, fromlist]]]) #可选参数默认为globals(),locals(),[] 从globals locals里面寻找fromlist里面的函数.
__import__(‘os’)    
__import__(‘os’,globals(),locals(),['xiaorui','fengyun'])  #等价于from os import xiaorui,fengyun

通常在动态加载时可以使用到这个函数,比如你希望加载某个文件夹下的所用模块,但是其下的模块名称又会经常变化时,就可以使用这个函数动态加载所有模块了,最常见的场景就是插件功能的支持。
扩展:
既然可以通过字符串来动态导入模块,那么是否可以通过字符串动态重新加载模块吗?试试reload(‘os’)直接报错。

In [145]: reload(‘os’)
—————————————————————————
TypeError                                 Traceback (most recent call last)
<ipython-input-145-e7052c614626> in <module>()
—-> 1 reload(‘os’)

TypeError: reload() argument must be module

记住 !不能直接reload一个字符串,但是可以有两种方法来解决你的需求。

第一种可以先unimport你指定的模块,然后再__import__、importlib重新加载模块。在python解释里可以通过globals(),locals(),vars(),dir()等函数查看到当前环境下加载的模块及其位置,除此之外sys.modules,通过sys.modules可以查看所有的已加载并且成功的模块。那么怎么让模块改成unimport状态? 直接删除….

第二种方法,比较优雅点… 其实方法的根据都是通过sys.modules来查找他的模块对象。另外模块的重新加载也不只是有reload这个函数,imp也有reload函数。暂时没发现啥区别。

一个小技巧:

locals() globals()可以看到详细的当前所有的对象。如果想看具体有啥,可以用dir(mq), vars(mq)更详细看到对象内置的信息。如果想实现所有模块重载,其实可以直接把globals里面对象,判断取出type为module的,然后加载一遍就行了。

 ’buzz.lib.mq’: <module ‘buzz.lib.mq’ from ‘buzz/lib/mq.pyc’>,
 ’buzz.lib.msgpack’: None,
 ’buzz.lib.os’: None,
 ’buzz.lib.pwd’: None,
 ’buzz.lib.re’: None,
 ’buzz.lib.redis’: None,
 ’buzz.lib.serialize’: <module ‘buzz.lib.serialize’ from ‘buzz/lib/serialize.pyc’>,
 ’buzz.lib.singleton’: <module ‘buzz.lib.singleton’ from ‘buzz/lib/singleton.pyc’>,

pyhton的解释器里面往往包含了一些内建函数,如果我们想重载所有模块的时候,可以首先去除内建函数。  imp.is_builtin() \  sys.builtin_module_names()

好了,开始介绍前几天提交的简约版的pyautoreload项目。 现在功能主要是模块导入及reload,过几天我会加入watch机制和信号机制。 


项目名:  pyautoreload

github:   https://github.com/rfyiamcool/pyautoreload

PYPI:     https://pypi.python.org/pypi/pyautoreload 


安装方法:

pypi安装


源码安装


使用方法:

重新加载指定模块

pyautoreload.reload_module(m)

加入模块

pyautoreload.import_str(‘a.b.c.d’)

路径: /a/b/c

函数: d

删除模块

delete_str(m)

重新加载所有模块

reload_all()

重新加载模块,支持类及函数路径模式

reload_str()



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品