文章目录
- 1. 使用reload方式重新加载库
- 2. 删除sys.modules中的缓存
- 3. 补充sys.path的知识
1. 使用reload方式重新加载库
import paddleocr
from importlib import reload
reload(paddleocr)
reload的模块必须是已经import过的模块,使用from XX import的不可以使用reload重新导入。
插曲
另外,使用的时候报出警告(后来发现这个错误是import的库的脚本中出现了import imp
才报错的,其实不用理睬):
DeprecationWarning: the imp module is deprecated in favour of importlib; see the module’s documentation for alternative uses
import imp, sys, os
似乎没有很好的答案:
问题
是一个简单的提示,Stack Overflow也有类似的问题,这里,似乎是pycharm的一个bug。。。查看pycharm的bug
2. 删除sys.modules中的缓存
由于reload没有解决我的问题,所以还是要另寻它法,参考知乎回答
简单介绍一下这个sys.modules
sys.modules是一个全局字典,该字典是python启动后就加载在内存中。
每当程序员导入新的模块,sys.modules都将记录这些模块。
字典sys.modules对于加载模块起到了缓冲的作用。
当某个模块第一次导入,字典sys.modules将自动记录该模块。
当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。
字典sys.modules具有字典所拥有的一切方法,可以通过这些方法了解当前的环境加载了哪些模块
但是我实际测试下来情况和这个不太一样,当前环境
,
import sys
sys.modules["os"]
Out[6]: <module 'os' from 'C:\\software\\anaconda\\lib\\os.py'>
> sys.modules["PaddleOCR"]
Traceback (most recent call last):
File "C:\software\anaconda\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-7-fe1fefe7f529>", line 1, in <module>
sys.modules["PaddleOCR"]
KeyError: 'PaddleOCR'
> sys.modules["paddleocr"]
Traceback (most recent call last):
File "C:\software\anaconda\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-8-8235e520a40a>", line 1, in <module>
sys.modules["paddleocr"]
KeyError: 'paddleocr'
另外,参考Python模块导入之sys.modules,再进行测试,效果差不多,可以看到第一次导入的时候就导入了大部分,之后再进行导入就沿用之前的内容。
import sys
modules1 = sys.modules.copy()
import paddleocr
modules2 = sys.modules.copy()
print('首次导入paddleocr模块后在sys.modules中加入的模块名:', modules2.keys() - modules1.keys())
> 'paddle.optimizer.rmsprop',
'paddle.fluid.layers.loss',
'paddle.distributed.fleet.meta_parallel.parallel_layers.mp_layers',
'__mp_main__',
'paddle.optimizer.lamb',
'cffi.model',
len(modules2.keys() - modules1.keys())
Out[15]: 1737
import paddleocr
modules3 = sys.modules
print('再次导入paddle模块后在sys.modules中加入的模块名:', modules3.keys() - modules2.keys())
> set()
for i in (modules2.keys()-modules1.keys()):
if "paddleocr" in i:
print(i)
> paddleocr
paddleocr.tools
paddleocr.tools.infer.utility
paddleocr.paddleocr
paddleocr.tools.infer
3. 补充sys.path的知识
主要参考菜鸟教程关于模块的部分
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
搜索路径
是一个解释器会先进行搜索的所有目录的列表
。搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块。
很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。
搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量
以我本机为例:
# 在pycharm的python控制台里输入以下命令
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
import sys
sys.path
# 输出的内容中首先就涵盖pycharm的目录
Out[3]:
['C:\\software\\PyCharm Community Edition 2020.3.2\\plugins\\python-ce\\helpers\\pydev',
'C:\\software\\PyCharm Community Edition 2020.3.2\\plugins\\python-ce\\helpers\\third_party\\thriftpy',
'C:\\software\\PyCharm Community Edition 2020.3.2\\plugins\\python-ce\\helpers\\pydev',
'C:\\software\\anaconda\\python37.zip',
'C:\\software\\anaconda\\DLLs',
'C:\\software\\anaconda\\lib',
'C:\\software\\anaconda',
'C:\\software\\anaconda\\lib\\site-packages',
'C:\\software\\anaconda\\lib\\site-packages\\win32',
'C:\\software\\anaconda\\lib\\site-packages\\win32\\lib',
'C:\\software\\anaconda\\lib\\site-packages\\Pythonwin',
'C:\\software\\anaconda\\lib\\site-packages\\IPython\\extensions',
'C:\\shaiic_work\\ZhiNengKeJiOCR',
'C:/shaiic_work/ZhiNengKeJiOCR']
如果是通常的命令行直接打印,则
>>> import sys >>> sys.path ['', 'C:\\software\\anaconda\\python37.zip', 'C:\\software\\anaconda\\DLLs', 'C:\\software\\anaconda\\lib', 'C:\\software\\anaconda', 'C:\\software\\anaconda\\lib\\site-packages', 'C:\\software\\anaconda\\lib\\site-packages\\win32', 'C:\\software\\anaconda\\lib\\site-packages\\win32\\lib', 'C:\\software\\anaconda\\lib\\site-packages\\Pythonwin']
sys.path 输出是一个列表,其中第一项是空串’',代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)。
因此若像我一样在当前目录下存在与要引入模块同名的文件,就会把要引入的模块屏蔽掉。
了解了搜索路径的概念,就可以在脚本中修改sys.path来引入一些不在搜索路径中的模块。