Python搜索路径错误,但仅限于Windows

2024-03-28 16:43:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个更大的逻辑包,分布在许多目录中,如下所示:

[projects root]/projectname1/lib/python/logicalpackage/__init__.py
[projects root]/projectname1/lib/python/logicalpackage/projectname1/__init__.py
[projects root]/projectname2/lib/python/logicalpackage/__init__.py
[projects root]/projectname2/lib/python/logicalpackage/projectname2/__init__.py

这样做的目的是:

^{pr2}$

在.bashrc或$profile(分别是bash和PowerShell)中有一个脚本之后,它将遍历[projects root]/*/lib/python/并导入它找到的包。在

我知道pkgutil是用来做这件事的,只要把代码片段放在__init__.pyfrom pkgutil import extend_path; __path__ = extend_path(__path__, __name__)中,我就可以让所有系统的一切都正常工作。不过,我的问题是,为什么当我不使用pkgutil时,它仍然可以正常工作,但只在某些平台上——特别是在OSX和Ubuntu(我见过的10和12)中,它可以工作,但在Windows(7)中却不行。我担心的是,使用pkgutil有一些我没有考虑的副作用。在

具体的非工作行为是,PYTHONPATH在脚本运行后似乎被正确地构造(在PowerShell中的.bashrc等效中),也就是说,我可以从Python中调试print PYTHONPATH,它与在另一个平台上构建的路径相同。但是,from projectname1 import foo成功,from projectname2 import bar失败(可能是因为projectname2稍后被alpha全局化)。这实际上是我在没有pkgutil的情况下所期望的行为。为什么在OSX和Ubuntu中没有这种行为?这个问题是由Windows或PowerShell的某种路径机制,还是在Windows上编译的Python二进制文件引起的,还是完全其他原因造成的?在

编辑:为了更清楚起见,添加以下内容:

# d:\projects> [Environment]::SetEnvironmentVariable("PYTHONPATH","d:\\projects\\projectname1\\lib\python;d:\\projects\\projectname2\\lib\\python;")
# d:\projects> echo $env:PYTHONPATH
# d:\\projects\\projectname1\\lib\python;e:\\projects\\projectname2\\lib\\python;
# d:\projects> python

import sys
sys.path
# => ['', '..python install dir..\\lib\\site-packages\\pip-1.2.1-py2.7.egg', 'd:\\projects\\projectname1\\lib\\python', 'd:\\projects\\projectname2\\lib\\python', ...usual stuff...]
import logicalpackage
logicalpackage.__path__
# => ['d:\\projects\\projectname1\\lib\\python\\logicalpackage']
import logicalpackage.projectname1 as p1
import logicalpackage.projectname2 as p2

# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ImportError: No module named projectname2
# exit()

用上面提到的pkgutils代码替换空的__init__.py

# d:\projects> python
import sys
sys.path
# => ['', 'D:\\usr\\Python27_32bit\\lib\\site-packages\\pip-1.2.1-py2.7.egg', 'd:\\projects\\projectname1\\lib\\python', 'd:\\projects\\projectname2\\lib\\python', 'd:\\projects', '...etc...']
import logicalpackage
logicalpackage.__path__
# => ['d:\\projects\\projectname1\\lib\\python\\logicalpackage', 'd:\\projects\\projectname2\\lib\\python\\logicalpackage']
import logicalpackage.projectname1 as p1
import logicalpackage.projectname2 as p2

注:没有例外。在通过pkgutil附加到模块路径之后让异常消失是预期的行为(对我和the documentation)——Python不应该附加到模块路径,除非我显式声明它。我想知道的是为什么Ubuntu上没有出现异常(换句话说,为什么它附加到模块路径而没有显式声明),不管我是否包含pkgutils代码段。在


Tags: pathpyimport路径initlibassys
3条回答

所以,这就是最终的问题。事实证明,pkgutils.extend_path将适用于扩展逻辑包中的每个模块,只要它包含在PYTHONPATH中该逻辑包的第一个实例中。在这两个环境中,PYTHONPATH前面都有一个environment模块,它包含extend_path。在Windows环境中,这个预先添加的路径实际上并不包含任何内容。我的失败基本上是没有意识到extend_path将扩展到PYTHONPATH中的所有逻辑包,即使该逻辑包中的特定模块不包含extend_path,只要第一个实例包含pkgutils片段。在

相关问题 更多 >