考虑像这样的Python项目:
contains
在正常情况下,尝试从foo/
__init__.py
scripts/
run.py
demo.sh
包导入
如果您从项目的根目录运行脚本,则会失败,因为默认的Python
行为是添加调用Python解释器的脚本的目录
(不一定是当前目录)到foo
。
(docs):
sys.path
然而,我最近注意到这样的进口正在我的盒子上工作,我 追踪它与PYTHONPATH相关的一些令人惊讶的行为。在我的Bash中 我已经为PYTHONPATH添加了一个目录:
python scripts/run.py
如果PYTHONPATH最初为空,那(有点草率,但常见) 命令的形式将留下一个尾随冒号:
export PYTHONPATH="/some/path:$PYTHONPATH"
我一直认为这个尾随标点没有影响,但它
似乎结尾的结肠是神秘成功的原因
进口。前导或尾随冒号(甚至是定义但空的PYTHONPATH)
将导致echo $PYTHONPATH
/some/path:
包含空字符串 sys.path
之前
模块加载,这反过来导致添加当前工作目录
到site
。
这是一个Python脚本和一个Bash脚本来演示。我也一样 使用Python 2.7和Python 3.3的行为。
Python脚本:sys.path
:
run.py
Bash脚本: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
:
demo.sh
我的问题:
我是否正确了解情况,或者我不知何故误入歧途?
这是否记录在任何地方?我没找到任何东西。至少,我是 在此处发布此信息以防其他人。
我是否一个人意外地发现这种行为?
答案 0 :(得分:3)
修改冒号分隔的环境变量时,例如PYTHONPATH,PATH,CPATH,MANPATH,LD_LIBRARY_PATH,PKG_CONFIG_PATH等等......其中一些变量对尾随冒号有特殊意义,而其他变量则没有。
对于PYTHONPATH和PATH,如果变量先前未设置,我建议以不会意外引入尾随(或前导)冒号的方式预先添加(或追加)新目录:
export PYTHONPATH="/some/path${PYTHONPATH+":"}${PYTHONPATH-}"
(在MANPATH和INFOPATH的情况下,你做想要引入一个尾部冒号,以便man
和info
包含它们的默认搜索目录。)
说明:
${PYTHONPATH+":"}
会扩展为:
,无论PYTHONPATH是否为空。 ${PYTHONPATH-}
将扩展为PYTHONPATH的内容(如果已设置),但如果未设置PYTHONPATH,则${PYTHONPATH-}
会扩展为空 - 就像通常的${PYTHONPATH}
一样
${PYTHONPATH-}
与${PYTHONPATH-""}
相同,意思是替换"" (没有)当PYTHONPATH未设置时。${PYTHONPATH-}
超过${PYTHONPATH}
的原因是,当{1}}未设置PYTHONPATH并且您的脚本已执行${PYTHONPATH-}
以在未设置时引发错误时,set -u
不会创建错误变量有关${parameter+[word]}
和${parameter-[word]}
机制的详细信息,请参阅"参数扩展"在http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
有关set -u
的详细信息,请参阅" set"的说明。在http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set