社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 炫技操作:模块重载的五种方法

Python编程时光 • 4 年前 • 1206 次点击  
点击上方“Python编程时光”,选择“加为星标
第一时间关注Python技术干货!

明哥原创的200页《PyCharm 中文指南》 震撼发布


系列文章

Python 炫技操作(01):条件语句的七种写法

Python 炫技操作(02):合并字典的七种方法

Python 炫技操作(03):连接列表的八种方法

Python 炫技操作(04):海象运算符的三种方法

Python 炫技操作(05):花式导包的八种方法

Python 炫技操作(06):判断是否包含子串的七种方法

环境准备

新建一个 foo 文件夹,其下包含一个 bar.py 文件

$ tree foo
foo
└── bar.py

0 directories, 1 file

bar.py 的内容非常简单,只写了个 print 语句

print("successful to be imported")

只要 bar.py 被导入一次,就被执行一次 print

禁止重复导入

由于有 sys.modules 的存在,当你导入一个已导入的模块时,实际上是没有效果的。

>>> from foo import bar
successful to be imported
>>> from foo import bar
>>>

重载模块方法一

如果你使用的 python2(记得前面在 foo 文件夹下加一个 __init__.py),有一个 reload 的方法可以直接使用

>>> from foo import bar
successful to be imported
>>> from foo import bar
>>>
>>> reload(bar)
successful to be imported
<module 'foo.bar' from 'foo/bar.pyc'>

如果你使用的 python3 那方法就多了,详细请看下面

重载模块方法二

如果你使用 Python3.0 -> 3.3,那么可以使用 imp.reload 方法

>>> from foo import bar
successful to be imported
>>> from foo import bar
>>>
>>> import imp
>>> imp.reload(bar)
successful to be imported
<module 'foo.barfrom  '/Users/MING/Code/Python/foo/bar.py'>

但是这个方法在 Python 3.4+,就不推荐使用了

:1: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

重载模块方法三

如果你使用的 Python 3.4+,请使用 importlib.reload 方法

>>> from foo import bar
successful to be imported
>>> from foo import bar
>>>
>>> import importlib
>>> importlib.reload(bar)
successful to be imported
<module 'foo.barfrom '/Users/MING/Code/Python/foo/bar.py'>

重载模块方法四

如果你对包的加载器有所了解(详细可以翻阅我以前写的文章:https://iswbm.com/84.html

还可以使用下面的方法

>>> from foo import bar
successful to be imported
>>> from foo import bar
>>>
>>> bar.__spec__.loader.load_module()
successful to be imported
<module 'foo.bar' from '/Users/MING/Code/Python/foo/bar.py'>

重载模块方法五

既然影响我们重复导入的是 sys.modules,那我们只要将已导入的包从其中移除是不是就好了呢?

>>> import foo.bar
successful to be imported
>>>
>>> import foo.bar
>>>
>>> import sys
>>> sys.modules['foo.bar']
<module 'foo.barfrom '/Users/MING/Code/Python/foo/bar.py'>
>>> del sys.modules['foo.bar']
>>>
>>> import foo.bar
successful to be imported

有没有发现在前面的例子里我使用的都是 from foo import bar,在这个例子里,却使用 import foo.bar,这是为什么呢?

这是因为如果你使用 from foo import bar 这种方式,想使用移除 sys.modules 来重载模块这种方法是失效的。

这应该算是一个小坑,不知道的人,会掉入坑中爬不出来。

>>> import foo.bar
successful to be imported
>>>
>>> import foo.bar
>>>
>>> import sys
>>> del sys.modules['foo.bar']
>>> from foo import bar
>>>


今天的文章就到这里了,如果对你有帮助,不如帮明哥三连一下(点赞、在看,转发)支持一下


文末福利

明哥整理了 21 张 Python 代码速查表,每一张都是国外的大师总结的,非常实用 ~

怎么获取呢?


添加明哥微信,备注 "速查表" 获取




推荐阅读


明哥写的 200页《PyCharm 中文指南》 终于发布了

《Python黑魔法指南》全新版本 v2.0 上线发布

15 款Python编辑器的优缺点,别再问我“选什么编辑器”啦!

超全!我把 Python 的 200个标准库整理出来了

刷爆全网的动态条形图,原来5行Python代码就能实现!

腾讯终于良心了!桌面混乱终于有救了

没有什么内存问题,是一行Python代码解决不了的

太牛逼了!一款软件几乎可以操作所有的数据库!



长按下图  ➡   关注博主

(按左边关注 Python, 按右边关注 Goalng


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/74191
 
1206 次点击