PYTHONPATH vs.sys.path


92

我和另一位开发人员不同意应该使用PYTHONPATH还是sys.path来允许Python在用户(例如,开发)目录中找到Python包。

我们有一个具有典型目录结构的Python项目:

Project
    setup.py
    package
        __init__.py
        lib.py
        script.py

在script.py中,我们需要这样做import package.lib。当该软件包安装在site-packages中时,script.py可以找到package.lib

但是,从用户目录工作时,还需要做其他事情。我的解决方案是将我的PYTHONPATH设置为包括“〜/ Project”。另一位开发人员希望将这行代码放在script.py的开头:

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

以便Python可以找到的本地副本package.lib

我认为这是一个坏主意,因为该行仅对开发人员或从本地副本运行的人有用,但是我不能给出一个很好的理由,说明它不是一个好主意。

我们应该使用PYTOHNPATH,sys.path还是很好?


4
似乎投票和答案在使用PYTHON_PATH的过程中相当平均地分配,尽管这可能是抽样噪音或问题的无意偏见。
AJP

Answers:


42

如果修改路径的唯一原因是让开发人员从其工作树中进行工作,则应使用安装工具为您设置环境。virtualenv非常流行,如果您使用setuptools,则可以运行setup.py develop以在当前Python安装中半安装工作树。


10
您可以对此提供更多说明吗?即使您站在conda / virtualenv环境中,这如何将顶级目录放在python路径上?
compguy24

38

我讨厌PYTHONPATH。我发现按用户(特别是对于守护程序用户)进行设置并跟踪项目文件夹的移动非常麻烦。我宁愿定下sys.path在独立项目的调用脚本中进行。

但是,sys.path.append这不是做到这一点的方法。您可以轻松获取重复项,并且不会对.pth文件进行分类。更好(更易读):site.addsitedir

而且script.py通常不会是更合适的位置,因为它位于要在路径中提供的包中。库模块当然不应与sys.path自己接触。取而代之的是,通常在用于实例化和运行应用程序的程序包之外会有一个hashbanged脚本,并且在此琐碎的包装脚本中,您要放置sys.path-frobbing之类的部署详细信息。


16
问题site.addsitedir在于它执行appendon sys.path,这意味着在开发中已安装的程序包将优先于本地程序包(可能会导致拔头发)。sys.path.insert(0...需要克服这一点。
伊莱·班德斯基2013年

5
@EliBendersky:应该是sys.path.insert(1stackoverflow.com/q/10095037/125507
endolith

12

通常,我会认为设置环境变量(例如PYTHONPATH)是一种不好的做法。尽管这对于一次性调试可能很好,但是将其作为
常规做法可能不是一个好主意。


其他人在代码库中报告问题时,使用环境变量会导致类似“对我有用”的情况。同样,对于测试环境,也可能会采用相同的做法,从而导致诸如测试对于特定开发人员运行良好的情况,但是当有人启动测试时可能会失败。


5

我认为,在这种情况下,使用PYTHONPATH是更好的选择,主要是因为它没有引入(可疑的)不必要的代码。

毕竟,如果您考虑了这一点,您的用户就不需要sys.path东西了,因为您的软件包将安装到站点软件包中,因为您将使用打包系统。

如果用户选择从“本地副本”(如您所说的)运行,那么我观察到,通常的做法是声明,如果在站点软件包之外使用,则必须手动将软件包添加到PYTHONPATH中。 。


5

除了已经提到的许多其他原因之外,您还可以指出硬编码

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

之所以很脆弱,是因为它假定script.py的位置-仅当script.py位于Project / package中时才起作用。如果用户决定将script.py(几乎)移动/复制/符号链接(几乎)在其他任何地方,它将中断。


2

由于前面提到的原因,黑客行为PYTHONPATHsys.path好主意都不是。而对于当前项目链接到的站点包文件夹中有实际上比一个更好的办法python setup.py develop,为解释在这里

pip install --editable path/to/project

如果您项目的根文件夹中没有setup.py,则可以从以下内容开始:

from setuptools import setup
setup('project')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.