PYTHONPATH与sys.path

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

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

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

在script.py中,我们需要import package.lib 。 当软件包安装在站点包中时,script.py可以findpackage.lib

但是,从用户目录进行工作时,还需要做其他事情。 我的解决scheme是设置我的PYTHONPATH包括“〜/项目”。 另一个开发者想把这行代码放在script.py的开头:

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

所以Python可以findpackage.lib的本地副本。

我认为这是一个坏主意,因为这条线只对开发者或从本地副本运行的人有用,但我不能给出一个很好的理由,为什么这是一个坏主意。

我们应该使用PYTOHNPATH,sys.path,还是罚款?

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

我讨厌PYTHONPATH。 我发现它很脆弱,很烦人,以每个用户为基础(尤其是守护进程用户),并随着项目文件夹的移动而跟踪。 我宁愿在独立项目的调用脚本中设置sys.path

但是sys.path.append不是这样做的。 你可以很容易得到重复的,它不会整理.pth文件。 更好(更可读): site.addsitedir

script.py通常不会是更适合的地方,因为它你想要在path上提供的包里面 。 库模块肯定不会碰到sys.path本身。 相反,你通常会在包之外有一个hashbanged脚本,用于实例化和运行应用程序,而且在这个简单的包装脚本中,你会放置像sys.path -frobbing这样的部署细节。

一般来说,我会考虑设置一个环境variables(比如PYTHONPATH)是一个糟糕的做法。 虽然这可能是罚款一个closuresdebugging,但使用此作为
定期的做法可能不是一个好主意。

环境variables的使用会导致某些情况,如“对我有用”
否则会报告代码库中的问题。 也可能有一些与testing环境相同的做法,导致像某些特定的开发者可以正常运行的testing,但是当某个testing开始时可能会失败。

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

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

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

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

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

如果用户select从“本地副本”运行,就像你所说的那样,那么我已经注意到,通常的做法是声明,如果在站点包之外使用包,则需要手动将包添加到PYTHONPATH中。