103

另一位开发人员和我不同意是否PYTHONPATHsys.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.

但是,当从用户目录工作时,需要做其他事情。我的解决方案是将 my 设置PYTHONPATH为包含"~/Project". 另一个开发者想把这行代码放在 script.py 的开头:

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

这样 Python 就可以找到package.lib.

我认为这是一个坏主意,因为这条线仅对开发人员或从本地副本运行的人有用,但我无法给出一个坏主意的充分理由。

我们应该使用PYTOHNPATH,sys.path还是可以?

4

6 回答 6

42

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

于 2009-12-12T14:39:06.753 回答
40

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

然而sys.path.append并不是这样做的方法。您可以轻松获得重复项,并且它不会整理.pth文件。更好(并且更具可读性)site.addsitedir:.

而且script.py通常不会是更合适的地方,因为它位于您希望在路径上可用的包内。库模块当然不应该接触sys.path它们自己。相反,您通常会在用于实例化和运行应用程序的包之外有一个 hashbanged-script,在这个简单的包装脚本中,您可以放置​​部署细节,例如sys.path-frobbing。

于 2009-12-12T14:54:30.283 回答
13

一般来说,我认为设置环境变量(如 PYTHONPATH)是一种不好的做法。虽然这对于一次性调试可能很好,但将其用作
常规做法可能不是一个好主意。


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

于 2009-12-12T17:06:49.553 回答
11

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

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

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

于 2009-12-12T15:44:19.933 回答
5

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

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

如果用户选择从“本地副本”运行,正如您所说,那么我观察到,通常的做法是声明,如果在站点包之外使用,则需要手动将包添加到 PYTHONPATH .

于 2009-12-12T14:40:48.220 回答
5

由于前面提到的原因,黑客攻击PYTHONPATH也不是一个好主意。sys.path对于将当前项目链接到 site-packages 文件夹,实际上有比 更好的方法python setup.py develop如下所述:

pip install --editable path/to/project

如果您的项目的根文件夹中还没有 setup.py,那么这个就足够了:

from setuptools import setup
setup('project')
于 2020-01-03T14:50:18.180 回答