如何设置 Python 模块搜索路径

我被代码海扁署名-非商业-禁演绎
阅读 12:35·字数 3778·更新 
Bilibili 空间
关注 960

前提

阅读本节的前提是对 Python 模块搜索路径有所掌握,你可以查看Python 模块搜索路径介绍,Python 模块搜索路径中的目录有哪些一节来了解相关信息。

设置 Python 模块搜索路径

为了让需要导入的模块可以被正确的找到,我们可能要对 Python 模块搜索路径进行设置,而以下是几种用于设置模块搜索路径的方法。

为何设置 Python 模块搜索路径后没有效果?

如果设置 Python 模块搜索路径没有效果,那么原因可能有多种,比如,对环境变量的修改尚不能被 Python 读取,需要进行重启(比如,重启命令行),或使用_pth文件重写了所有的 Python 模块搜索路径。

重写搜索路径

关于_pth文件的使用,你可以查看如何使用 _pth 文件重写 Python 模块搜索路径一节。

使用 sys.path 设置 Python 模块搜索路径

在 Python 启动后,模块搜索路径等同于sys模块的path变量,该变量是一个列表对象,添加目录至path或删除path中的目录,都将影响模块搜索路径。

设置 sys.path 对 Python 模块搜索路径的影响是有限的

需要注意的是,修改sys.path所造成的影响,仅对此运行中的 Python 有效。

在脚本文件set_path.py中,tree.py所在的目录plants被添加至sys.pathplantsset_path.py处于同一目录),因此可以直接书写import tree来导入模块treeset_path.py所在的目录将成为模块搜索路径的一部分)。

将命令行切换至set_path.py所在的目录,然后运行set_path.py,可以看到tree模块的输出信息。

set_path.py
# 获取文件夹 plants 的绝对路径
import os
import sys
plants_path = os.path.abspath('plants')

# 将文件夹 plants 的绝对路径添加至模块搜索路径 sys.path.append(plants_path)
# 直接导入 plants 中的 tree 模块 import tree
plants/tree.py
print('哦?这是一颗树?')
Windows
python set_path.py
哦?这是一颗树?
UNIX/Linux/macOS
python3 set_path.py
哦?这是一颗树?

使用环境变量 PYTHONPATH 设置 Python 模块搜索路径

设置环境变量PYTHONPATH,将为模块搜索路径添加一组目录,他们可以是相对或绝对路径。当你希望设置自己的 Python 标准/扩展库时,可以把相关目录放入PYTHONPATH中。

PYTHONPATH的设置方式类似于环境变量PATH,在 Windows 中采用;分隔多个目录,在 UNIX/Linux/macOS 中则是:

变更后的环境变量 PYTHONPATH 可能无法对 Python 立即产生影响

在一般的使用场景中,环境变量PYTHONPATH是由运行 Python 的命令行应用提供的,如果再次启动 Python 后模块搜索路径没有变化,那么可能是因为变更尚不能被命令行识别或应用,他为 Python 提供了与之前一样的PYTHONPATH

设置环境变量

关于如何设置环境变量,你可以查看编程指南如何设置 Windows 环境变量如何设置 UNIX/Linux/macOS 环境变量两节。

使用 pth 文件设置 Python 模块搜索路径

通过在第三方包目录中新建pth文件,同样可以为模块搜索路径添加目录,pth文件对文件名没有特殊要求,每个目录均作为单独的一行保存在文件中,他们可以是相对或绝对路径。

pth 文件中列出的目录需要真实存在

与使用sys.path,环境变量PYTHONPATH以及稍后提到的 Windows 注册表不同,pth文件所列出的目录必须是真实存在的,否则,他们不会被添加至 Python 模块搜索路径。

pth 文件允许编写 Python 代码

除了路径,你还可以在pth文件中写入简单的代码,相关联的代码应该保持在同一行,因为不同行的代码会被分开执行,多个语句之间可以使用;进行分隔。比如,书写import sys;sys.path.append('custom_lib')会将相对路径custom_lib添加到sys.path

如何在 pth 文件中添加注释?

在一行的开始位置使用#后,该行即成为 pth 文件的注释。

第三方包

要了解第三方包的具体位置,你可以查看Python 第三方包的位置一段。

下面名为my.pth的文件,包含了一个相对路径,一行注释,以及一行简单的代码。

my.pth
my_modules
# 这是一行注释哦!
import sys;sys.path.append('custom_lib')

使用 Windows 注册表设置 Python 模块搜索路径

如果你在使用 Windows,那么注册表也是设置模块搜索路径的途径之一,注册表键HKEY_CURRENT_USER\Software\Python\PythonCore\<X>.<Y>\PythonPathHKEY_LOCAL_MACHINE\Software\Python\PythonCore\<X>.<Y>\PythonPath的默认值应包含相应的目录,他们可以是相对或绝对路径,多个目录之间使用;进行分隔。

上述X为需要设置搜索路径的 Python 的主要版本号,Y为次要版本号。

注册表键 HKEY_CURRENT_USER 和 HKEY_LOCAL_MACHINE 之间的区别

HKEY_CURRENT_USER中的注册表键和键值针对当前 Windows 用户,而HKEY_LOCAL_MACHINE中的注册表键和键值适用于所有 Windows 用户,当然,设置HKEY_LOCAL_MACHINE可能需要相关权限。

无论你选择设置HKEY_CURRENT_USER还是HKEY_LOCAL_MACHINE,或是两者皆选,他们包含的目录均会被添加至对应版本的 Python 的模块搜索路径中。

某些版本的 Python 可能不支持通过 Windows 注册表设置模块搜索路径

对于 Python 3.12 之前的版本,设置 Windows 注册表可能无法达到预期效果,但具体结果也可能因为 Windows 系统版本的不同而有所变化。

下面的reg文件,用于向注册表添加键HKEY_CURRENT_USER\Software\Python\PythonCore\3.12\PythonPath,其包含的目录将被添加至 3.12 版本的 Python。

my.reg
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Python\PythonCore\3.12\PythonPath] @="C:\\;custom_lib"

Python 模块搜索路径中的 zip 文件路径

在 Python 模块搜索路径中,不仅可以包含目录,还可以包含zip文件的路径,这些zip文件含有自己的目录结构和 Python 模块。因此,你可以将他们视为一种特殊的目录。

使用之前的文件tree.py创建压缩文件plants.zip,并在add_zip.py中将其绝对路径添加至模块搜索路径(plants.zipadd_zip.py位于同一文件夹),语句import tree会导入plants.zip中的tree模块。

将命令行切换至add_zip.py所在的目录,然后运行add_zip.py,将得到与之前一样的输出结果。

add_zip.py
# 获取压缩文件 plants.zip 的绝对路径
import os
import sys
zip_path = os.path.abspath('plants.zip')

# 将 plants.zip 的绝对路径添加至模块搜索路径 sys.path.append(zip_path)
# 导入 plants.zip 中的 tree 模块 import tree

在 Python 模块搜索路径中使用相对路径

Python 模块搜索路径允许使用相对路径,这些相对路径一般会转换为绝对路径(除非直接设置sys.path),在不同的设置方式中,相对路径所“相对”的目标可能不同。

Python sys.path 中的相对路径

对于sys模块的列表变量path,向其添加或其原本包含的任何相对路径,是指相对于当前工作目录。

如何查看 Python 的当前工作目录?

在 Python 的交互模式中,输入import osos.getcwd()两行代码,将显示当前工作目录。如果是py文件,可以改写os.getcwd()print(os.getcwd())

Python os 模块的 getcwd 函数

os模块的getcwd函数返回一个字符串,他以绝对路径的形式表示当前工作目录。

Windows
import os
os.getcwd()
''
UNIX/Linux/macOS
import os
os.getcwd()
'/usr/bin'
print_getcwd.py
# 显示当前工作目录
import os
print(os.getcwd())

PYTHONPATH 环境变量中的相对路径

对于环境变量PYTHONPATH中的相对路径,同样是相对于 Python 的当前目录,但在添加至sys.path时,他们将被转换为等价的绝对路径。

假设 Windows 存在环境变量PYTHONPATH,其值为custom_lib\hello;system_lib,当前工作目录为C:\,那么sys.path将包含C:\custom_lib\helloC:\system_lib

Python pth 文件中的相对路径

需要注意,pth文件中包含的相对路径,是相对于该文件所在的目录,而非 Python 的当前工作目录。在被添加至sys.path时,他们会转换为等价的绝对路径。

假设 Windows 中 Python 的第三方包目录为C:\python\Lib\site-packages,该目录拥有文件my.pth并包含相对路径custom_lib\hellosystem_lib,那么常规启动后,sys.path将包含C:\python\Lib\site-packages\custom_lib\helloC:\python\Lib\site-packages\system_lib

Windows 注册表中的相对路径

在 Windows 系统中,注册表键HKEY_CURRENT_USER\Software\Python\PythonCore\<X>.<Y>\PythonPathHKEY_LOCAL_MACHINE\Software\Python\PythonCore\<X>.<Y>\PythonPath中的相对路径,与环境变量PYTHONPATH中的相对路径类似,他们相对于当前工作目录,并在添加至sys.path时被转换为绝对路径。

上述X为 Python 主要版本号,Y为次要版本号。

源码

set_path.py·codebeatme/python-reference·GitHub
plants/tree.py·codebeatme/python-reference·GitHub
my.pth·codebeatme/python-reference·GitHub
my.reg·codebeatme/python-reference·GitHub
add_zip.py·codebeatme/python-reference·GitHub
print_getcwd.py·codebeatme/python-reference·GitHub