您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python 的模块搜索路径!

5b51 2022/1/14 8:24:34 python 字数 12390 阅读 633 来源 www.jb51.cc/python

一种语言要使用到外部库(模块)时必然会涉及到从哪里以及按何顺序加载依赖,就像LD_LIBRARY_PATH,CLASSPATH那样,Python也有其默认的模块搜索顺序,依序找到想要的模块即停止。Python中sys.path返回的列表包含了模块搜

概述

@H_404_0@一种语言要使用到外部库(模块) 时必然会涉及到从哪里以及按何顺序加载依赖,就像 LD_LIBRARY_PATH,CLASSPATH 那样,Python 也有其认的模块搜索顺序,依序找到想要的模块即停止。Python 中 sys.path 返回的列表包含了模块搜索的顺序,我们可以程序中修改该列表,或用 PYTHONPATH 环境变量前插路径,甚至是用 .pth 文件来附加路径。

@H_404_0@简单的,可以执行命令 python3 -c "import sys; print(str(sys.path).replace(',',' '))" 来查看 python3 交互 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']

@H_404_0@注意,第一个元素是个空字符串,代表进入 python3 shell 时的当前目录。

@H_404_0@如果在通过一个 py 脚本文件来打印 sys.path 的话显示稍微有所差异。比如在目录 /home/yanbin/Developers/ 下创建 test.py 文件内容

import sys

for line in sys.path:
print(f"'{line}'")

for line in sys.path:
print(f"'{line}'")

for line in sys.path:
print(f"'{line}'")

@H_404_0@而我们退到 /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'

@H_404_0@第一行的路径有所不同了,变成了一个绝对路径,也就是说 test.py 可以从它所在目录上加载模块。比如在 /home/yanbin/Developers 下有 mymath.py,在 test.py 中能够直接 import mymath 成功。但是把 mymath.py 放到当前目录 /home/yanbin 下就加载不到了。除非用 PYTHONPATH 指定当前目录 .,后面会讲到。

@H_404_0@再次重复一下 Python shell 与执行脚本文件时,模块搜索路径第一个路径显示方式不一样,Python shell 下用空字符串表示进行 shell 时的当前目录,执行脚本时第一个路径是脚本文件所在的目录。Shell 启动时目录或脚本所以在目录总是最高优先级的模块搜索路径。

@H_404_0@接下来介绍如何动态修改 sys.path 以及用环境变量 PYTHONPATH 如何影响 sys.path 来增加新的搜索路径。至于用 .pth 文件附加路径的方式后面会另立新篇。

@H_404_0@动态修改 sys.path

@H_404_0@sys.path 是一个可变的列表,所以运行时可以随便修改它的内容,比如说想要加载 /home/yanbin/test 下的 mymath 模块,但是它没出现在 sys.path 列表中,我们可以这样做

import sys

sys.path.append('/home/yanbin/test')
import mymath
print(mymath.pi)

sys.path.append('/home/yanbin/test')
import mymath
print(mymath.pi)

sys.path.append('/home/yanbin/test')
import mymath
print(mymath.pi)

@H_404_0@这只是一条路子,程序中不应该经常性的这么做,因为 sys.path 是一个全局变量,如果运行时想改就改,最终不知道模块是从哪儿加载过来的。相比,下面的 PYTHONPATH 比较实用些

@H_404_0@PYTHONPATH 环境变量向前添加模块搜索路径

@H_404_0@如果用环境变量 PYTHONPATH 设置了模块搜索路径,它的内容将被向前添加到 sys.path 列表中去,准确来讲是插入到 sys.path 的第一个元素后面。 PYTHONPATH 中可以使用绝对路径和相对路径,相对路径是相对于 Shell 启动时的目录或脚本文件所在的目录。

@H_404_0@举例来看

@H_404_0@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'

@H_404_0@看到相对路径 extra_modules 相对于进入 shell 前的 / 目录,效果上相当于

sys.path[1:1] = ['/home/yanbin/test','/extra_modules']

@H_404_0@脚本文件的方式

@H_404_0@这一次我们在 PYTHONPATH 中把当前路径给加上

$ export PYTHONPATH=.:/home/yanbin/test:extra_modules
$ cd /home/yanbin
$ python3 Developers/test.py

@H_404_0@输出如下

'/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'

@H_404_0@第一行为脚本文件所在的目录, /home/yanbin 为 PYTHONPATH 中的 . 。这样我们既能够从脚本所在的目录,也可以从当前工作目录中加载模块了,惊喜就是 cd 切换一下目录后代码就可能不工作了。

@H_404_0@小结:

总结

以上是编程之家为你收集整理的Python 的模块搜索路径!全部内容,希望文章能够帮你解决Python 的模块搜索路径!所遇到的程序开发问题。


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶