【发布时间】:2015-11-09 17:54:12
【问题描述】:
考虑一个这样的 Python 项目:
foo/
__init__.py
scripts/
run.py
demo.sh
一般情况下,尝试从foo包导入会
如果从项目的根目录运行脚本会失败,因为默认的 Python
行为是添加 调用 Python 解释器的脚本目录
(不一定是当前目录)到sys.path。
(docs):
python scripts/run.py
但是,我最近注意到此类导入正在我的盒子上工作,我 将其归结为与 PYTHONPATH 相关的一些令人惊讶的行为。在我的 Bash profile 我已经向 PYTHONPATH 添加了一个目录:
export PYTHONPATH="/some/path:$PYTHONPATH"
如果 PYTHONPATH 最初是空的,那(有点草率,但很常见) 命令的形式会留下一个尾随冒号:
echo $PYTHONPATH
/some/path:
我一直认为这个尾随标点没有影响,但它
似乎尾随的冒号是神秘成功的原因
进口。前导或尾随冒号(甚至是已定义但为空的 PYTHONPATH)
将导致sys.path 在site 之前 包含一个空字符串
模块加载,这反过来又导致当前工作目录被添加
到sys.path。
这里有一个 Python 脚本和一个 Bash 脚本来演示。我也一样 使用 Python 2.7 和 Python 3.3 时的行为。
Python 脚本:run.py:
import sys, os
pp = os.environ.get('PYTHONPATH')
try:
import foo
print 'OK'
assert os.getcwd() in sys.path
assert pp == '' or pp.startswith(':') or pp.endswith(':')
except Exception:
print 'FAIL'
assert os.getcwd() not in sys.path
assert pp is None
Bash 脚本:demo.sh:
# Import fails.
unset PYTHONPATH; python scripts/run.py
# Import succeeds -- to my surprise.
PYTHONPATH='' python scripts/run.py
PYTHONPATH='/tmp:' python scripts/run.py
PYTHONPATH=':/tmp' python scripts/run.py
我的问题:
我是否正确理解了情况,或者我是否误入歧途?
这是否记录在任何地方?我什么也没找到。至少,我是 在此处发布此信息以防对其他人有所帮助。
只有我一个人发现这种行为出乎意料吗?
【问题讨论】:
-
无法在 Windows 上复制。
-
您对正在发生的事情是正确的,我发现这种行为出乎意料且不受欢迎。向 python 恕我直言报告错误是值得的,除了像这样长期存在的怪事在修复后会破坏事情。
-
或者我收回它。
export "PATH=$PATH:" lets本地路径中的命令在 linux 上执行。 Python 的工作方式相同。 -
@tdelaney 谢谢——这是一个很好的测试。我想 Python 的行为根据 Unix 的行为是有意义的……但它们似乎都违反直觉。也许这里有很深的逻辑。
-
是的 - 只是重复了你的发现,然后谷歌搜索“python路径尾随冒号”并偶然发现了你的答案。至少可以说似乎次优。
标签: python import pythonpath sys.path