另一位开发人员和我不同意是否应该使用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,还是可以?
答案 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)
由于上述原因,入侵PYTHONPATH
和sys.path
都不是一个好主意。对于将当前项目链接到site-packages文件夹中,实际上还有一种比python setup.py develop
更好的方法,如here所述:
pip install --editable path/to/project
如果您项目的根文件夹中没有setup.py,则可以从以下内容开始:
from setuptools import setup
setup('project')