PYTHONPATH
前言:
如果你是个Python开发者,日常工作和学习过程中绝对遇到过ImportError、ModuleNotFoundError
这个错误,有可能提示你模块路径不对,或者找不到模块等等。这时候就需要确定导入的模块是不是存在PYTHONPATH当中了
一、什么是包,什么是模块
🚀 一句话:“模块” 就是xx.py, “包” 包含了很多的模块xx.py并且可以直接导入使用
二、Import 到底做了什么?
1、sys.path
如果你有意去观察sys.path
的输出,你就会发现,sys.path
输出的第一个字符串路径会是你当前包的路径。这就是为什么同一个路径下导入模块不会报ModuleNotFoundError
, 而你在导入其他路径的模块或者包时会出现问题的原因。
Pycharm会帮我们自动导入当前环境的sys.path
。
2、if __name__ == “__main__”
但是, Import 在导入模块时会运行模块内的所有代码,如果我们直接在被倒入的模块内写了运行代码,比如:xx.run(),那么这个模块被导入时就会自动运行。所以,你应该看到过这行代码if __name__ == "__main__"
。它的作用就是检测当前运行的模块名称是不是调用者本身。
下图有a.py 和 b.py两个文件
a.py 只输出本身的__name__
b.py 导入了a.py,并且输出了__name__
最后看到运行b.py时,a.py的输出结果变成了a(模块名称), 而b.py输出结果是__main__
三、PYTHONPATH要如何修改:
基础路径信息如上
假设需要在mian.py 中导入 util.length, 你要写入的是import util.length
而不能是 import length
,后者的结果会是: ModuleNotFoundError: No module named ‘length’
因为你会发现当前路径中并不存在 length.py
的路径,所以需要添加那个路径才能找得着。
1、sys.path中添加需要导入的路径
# 我们可以在头部添加这行代码,让sys.path中加入指定包的路径,这样python解释器就可以找到了
import sys
fpath = os.path.join(os.path.dirname(__file__), 'utils')
sys.path.append (fpath)
2、修改PYTHONPATH环境变量
PYTHONPATH 是一个环境变量,你可以设置它来添加额外的目录,python 将在其中查找模块和包
可以看到如果没有添加PYTHONPATH,就会报错。如果添加了指定的包路径,就没问题了。
export的意义是临时添加,不用担心它会永久生效,他只会在你的环境中存在,另一个用户登录后就不存在了。$PYTHONPATH:
的意思是继承之前的路径,“:” 用来做路径的分隔符。
3、__init__.py 是做什么?
__init__.py 是每个python程序运行时第一个运行的脚本文件,并且会根据sys.path中路径寻找我们导入的模块。我们可以根据这个特性,将导入模块的工作交给它。
这里我在utils里加入了__init__.py,我的运行路径是黄色框 /tmp/note/module_import,所以我需要在init里从from utils开始写,而不是from length import get_length。正如上边sys.path所说,python解释器会从当前运行目录下开始寻找,除非添加了额外的sys.path或者PYTHONPATH。
四、所以说那种方式更好?
其实以上三种方式,最常用的是__init__.py,在转换另一个环境后也更方便使用。sys.path的话其实也可以,就是别人开起来会比较繁琐,或者使用PYTHONPATH在应用的运行环境里直接添加运行路径。这三种方式也是因人而异的。当然如果你有更好的解释,请留下宝贵的见解,感谢!