PYTHONPATH与sys.path

时间:2009-12-12 14:33:37

标签: python python-import pythonpath sys.path

另一位开发人员和我不同意是否应该使用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,还是可以?

6 个答案:

答案 0 :(得分:41)

如果修改路径的唯一原因是开发人员在其工作树中工作,那么您应该使用安装工具为您设置环境。 virtualenv非常受欢迎,如果您使用的是setuptools,只需运行setup.py develop即可在当前的Python安装中半安装工作树。

答案 1 :(得分:34)

我讨厌PYTHONPATH。我发现在每个用户的基础上设置(特别是对于守护程序用户)并且在项目文件夹移动时跟踪它是脆弱和烦人的。我宁愿在独立项目的调用脚本中设置sys.path

然而sys.path.append不是这样做的。您可以轻松获取重复项,但不会对.pth个文件进行排序。更好(也更可读):site.addsitedir

并且script.py通常不是更合适的地方,因为它是里面你希望在路径上提供的包。图书馆模块当然不应该自己接触sys.path。相反,您通常在用于实例化和运行应用程序的程序包外部有一个hashbanged-script脚本,而在这个简单的包装器脚本中,您可以部署详细信息,如sys.path - frobbing。

答案 2 :(得分:10)

一般来说,我会考虑设置一个环境变量(比如PYTHONPATH) 是一个不好的做法。虽然这可能适用于一次性调试,但使用此作为
经常练习可能不是一个好主意。

环境变量的使用会导致某些情况下“适用于我”的情况 否则报告代码库中的问题。也有人可能会采用相同的做法 测试环境,导致测试运行正常的情况 特别是开发人员,但是当有人启动测试时可能会失败。

答案 3 :(得分:5)

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

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

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

答案 4 :(得分:4)

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

毕竟,如果你想到它,你的用户就不需要那个sys.path的东西,因为你的软件包将被安装到site-packages中,因为你将使用一个包装系统。

如果用户选择从“本地副本”运行,就像你调用它一样,那么我已经观察到,通常的做法是说明需要手动将包添加到PYTHONPATH,如果在外面使用站点包。

答案 5 :(得分:2)

由于上述原因,入侵PYTHONPATHsys.path都不是一个好主意。对于将当前项目链接到site-packages文件夹中,实际上还有一种比python setup.py develop更好的方法,如here所述:

pip install --editable path/to/project

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

from setuptools import setup
setup('project')