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

标签 python linux windows macos

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

[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

我们的想法是能够做到这一点:

import logicalpackage.projectname1 as p1
import logicalpackage.projectname2 as p2

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

我知道pkgutil为此,通过将该代码段粘贴到 __init__.py (from pkgutil importextend_path; __path__ =extend_path(__path__, __name__) 中,当我这样做时,我可以让所有系统在所有系统上正常工作。不过,我的问题是,为什么当我使用 pkgutil 时,这仍然可以正常工作,但仅限于某些平台 - 特别是在 OSX 和 Ubuntu(10 和 10)中我见过的 12),它可以工作,但在 Windows (7) 中却不能。我担心的是使用 pkgutil 会产生一些我没有考虑到的副作用。

具体的非工作行为是,在该脚本运行后,PYTHONPATH 似乎已正确构建(在 PowerShell 中的 .bashrc 等效项中),即我可以从 Python 中调试 print PYTHONPATH,它与在另一个平台上构建的路径相同。但是,from projectname1 import foo 成功,from projectname2 import bar 失败(大概是因为projectname2 后来被 alpha 通配了)。这实际上是我在没有 pkg​​util 的情况下所期望的行为。为什么 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

注意:也不异常(exception)。通过 pkgutil 附加到模块路径后,异常消失是预期的行为(对我来说,以及 the documentation )——Python 不应该附加到模块路径,除非我明确声明它。我想知道为什么 Ubuntu 上没有发生异常(换句话说,为什么它附加到模块路径而没有明确声明),无论我是否包含 pkgutils 代码段。

最佳答案

所以,这就是最终的问题所在。事实证明,pkgutils.extend_path 适用于扩展逻辑包中的每个模块,只要它包含在 PYTHONPATH 中该逻辑包的第一个实例中即可。在这两种环境中,PYTHONPATH 都以 ticalpackage 中包含的 environment 模块为前缀,其中包含 extend_path。在 Windows 环境中,该前置路径实际上不包含任何内容。我的失败基本上是因为没有认识到 extend_path 将扩展到 PYTHONPATH 中的所有逻辑包,即使该逻辑包中的特定模块不包含 extend_path,只要第一个实例包含 pkgutils 代码段。

关于Python搜索路径错误,但仅限于Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20287880/

相关文章:

python - "str indices must be integers"是什么意思?

linux - 如何借助shell脚本通过IP知道目标计算机正在使用的操作系统?

c - 消息队列 - 多个进程在 msgqueue 上发送 cmd

c++ - 我应该使用 std::system 来编写单元测试的脚本部分吗?

python - Eventlet 的生成不起作用。这么奇怪

java-如何编写一个进程来拦截在远程计算机上运行的程序的输出流/知道远程程序何时停止/完成

python - 从 Flash 客户端验证文件真实性而不泄露 key

linux - 如果按字母顺序排列,使用 Sed 只删除文件名中的第一个字符

node.js - 如何在NPM任务中为node.js设置环境变量

java - 我无法在 Windows 10 计算机中安装 Java