内容简介:一种语言要使用到外部库(模块) 时必然会涉及到从哪里以及按何顺序加载依赖,就像 LD_LIBRARY_PATH, CLASSPATH 那样,Python 也有其默认的模块搜索顺序, 依序找到想要的模块即停止。Python 中简单的,可以执行命令注意,第一个元素是个空字符串,代表进入 python3 shell 时的当前目录。
一种语言要使用到外部库(模块) 时必然会涉及到从哪里以及按何顺序加载依赖,就像 LD_LIBRARY_PATH, CLASSPATH 那样,Python 也有其默认的模块搜索顺序, 依序找到想要的模块即停止。Python 中 sys.path
返回的列表包含了模块搜索的顺序,我们可以程序中修改该列表,或用 PYTHONPATH
环境变量前插路径,甚至是用 .pth
文件来附加路径。
简单的,可以执行命令 python3 -c "import sys; print(str(sys.path).replace(',', '\n'))"
来查看 python 3 交互 shell 下的模块搜索路径,类似结果如下:
['' '/usr/lib/python36.zip' '/usr/lib/python3.6' '/usr/lib/python3.6/lib-dynload' '/home/yanbin/.local/lib/python3.6/site-packages' '/usr/local/lib/python3.6/dist-packages' '/usr/lib/python3/dist-packages' '/usr/lib/python3.6/dist-packages']
注意,第一个元素是个空字符串,代表进入 python3 shell 时的当前目录。
如果在通过一个 py 脚本文件来打印 sys.path
的话显示稍微有所差异。比如在目录 /home/yanbin/Developers/
下创建 test.py
文件,内容为
import sys for line in sys.path: print(f"'{line}'")
而我们退到 /home/yanbin
为当前目录来执行 python3 Developers/test.py
, 显示出来的搜索路径如下:
'/home/yanbin/Developers' '/usr/lib/python36.zip' '/usr/lib/python3.6' '/usr/lib/python3.6/lib-dynload' '/home/yanbin/.local/lib/python3.6/site-packages' '/usr/local/lib/python3.6/dist-packages' '/usr/lib/python3/dist-packages' '/usr/lib/python3.6/dist-packages'
第一行的路径有所不同了,变成了一个绝对路径,也就是说 test.py
可以从它所在目录上加载模块。比如在 /home/yanbin/Developers
下有 mymath.py
, 在 test.py
中能够直接 import mymath
成功。但是把 mymath.py
放到当前目录 /home/yanbin
下就加载不到了。除非用 PYTHONPATH
指定当前目录 .
, 后面会讲到。
再次重复一下 Python shell 与执行脚本文件时,模块搜索路径第一个路径显示方式不一样,Python shell 下用空字符串表示进行 shell 时的当前目录,执行脚本时第一个路径是脚本文件所在的目录。Shell 启动时目录或脚本所以在目录总是最高优先级的模块搜索路径。
接下来介绍如何动态修改 sys.path
以及用环境变量 PYTHONPATH
如何影响 sys.path
来增加新的搜索路径。至于用 .pth
文件附加路径的方式后面会另立新篇。
动态修改 sys.path
sys.path
是一个可变的列表,所以运行时可以随便修改它的内容,比如说想要加载 /home/yanbin/test
下的 mymath 模块,但是它没出现在 sys.path
列表中,我们可以这样做
import sys sys.path.append('/home/yanbin/test') import mymath print(mymath.pi)
这只是一条路子,程序中不应该经常性的这么做,因为 sys.path
是一个全局变量,如果运行时想改就改,最终不知道模块是从哪儿加载过来的。相比,下面的 PYTHONPATH
比较实用些
PYTHONPATH
环境变量向前添加模块搜索路径
如果用环境变量 PYTHONPATH
设置了模块搜索路径,它的内容将被向前添加到 sys.path
列表中去,准确来讲是插入到 sys.path
的第一个元素后面。 PYTHONPATH
中可以使用绝对路径和相对路径,相对路径是相对于 Shell 启动时的目录或脚本文件所在的目录。
举例来看
python shell
$ export PYTHONPATH=/home/yanbin/test:extra_modules $ cd / $ python3 >>> import sys >>> for line in sys.path: ... print(f"'{line}'") ... '' '/home/yanbin/test' '/extra_modules' '/usr/lib/python36.zip' '/usr/lib/python3.6' '/usr/lib/python3.6/lib-dynload' '/home/yanbin/.local/lib/python3.6/site-packages' '/usr/local/lib/python3.6/dist-packages' '/usr/lib/python3/dist-packages' '/usr/lib/python3.6/dist-packages'
看到相对路径 extra_modules
相对于进入 shell 前的 /
目录,效果上相当于
sys.path[1:1] = ['/home/yanbin/test', '/extra_modules']
脚本文件的方式
这一次我们在 PYTHONPATH
中把当前路径给加上
$ export PYTHONPATH=.:/home/yanbin/test:extra_modules $ cd /home/yanbin $ python3 Developers/test.py
输出如下
'/home/yanbin/Developers' '/home/yanbin' '/home/yanbin/test' '/home/yanbin/extra_modules' '/usr/lib/python36.zip' '/usr/lib/python3.6' '/usr/lib/python3.6/lib-dynload' '/home/yanbin/.local/lib/python3.6/site-packages' '/usr/local/lib/python3.6/dist-packages' '/usr/lib/python3/dist-packages' '/usr/lib/python3.6/dist-packages'
第一行为脚本文件所在的目录, /home/yanbin
为 PYTHONPATH
中的 .
。这样我们既能够从脚本所在的目录,也可以从当前工作目录中加载模块了,惊喜就是 cd 切换一下目录后代码就可能不工作了。
小结:
- sys.path 能列出模块搜索顺序,Python REPL 中第一个路径为空字符串,代表 Shell 启动时的目录,执行脚本文件时第一个路径是脚本文件所在的目录
-
PYTHONPATH
环境变量可以使用绝对和相对路径。相对路径相对于 Shell 启动时目录或程序脚本文件所在目录 -
PYTHONPATH
中的所有路径会以sys.path[1:1] = <paths in PYTHONPATH>
的方式添加到sys.path
搜索路径列表中 -
动态的改动
sys.path
应该尽量少用吧
以上所述就是小编给大家介绍的《Python 的模块搜索路径》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Nodejs教程12:path(路径)模块
- 深入解析Java绝对路径与相对路径
- C#/.NET 如何确认一个路径是否是合法的文件路径
- GAC 与其物理路径
- 关键渲染路径优化
- 【Leetcode】62. 不同路径
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Compilers
Alfred V. Aho、Monica S. Lam、Ravi Sethi、Jeffrey D. Ullman / Addison Wesley / 2006-9-10 / USD 186.80
This book provides the foundation for understanding the theory and pracitce of compilers. Revised and updated, it reflects the current state of compilation. Every chapter has been completely revised ......一起来看看 《Compilers》 这本书的介绍吧!