PYTHONPATH 与 sys.path
另一位开发人员和我对于是否应使用 PYTHONPATH 或 sys.path 来允许 Python 在用户(例如开发)目录中查找 Python 包存在分歧。
我们有一个具有典型目录结构的Python项目:
Project
setup.py
package
__init__.py
lib.py
script.py
在script.py中,我们需要导入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 还是两者都可以?
Another developer and I disagree about whether PYTHONPATH
or sys.path
should be used to allow Python to find a Python package in a user (e.g., development) directory.
We have a Python project with a typical directory structure:
Project
setup.py
package
__init__.py
lib.py
script.py
In script.py, we need to do import package.lib
. When the package is installed in site-packages, script.py can find package.lib
.
When working from a user directory, however, something else needs to be done. My solution is to set my PYTHONPATH
to include "~/Project"
. Another developer wants to put this line of code in the beginning of script.py:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
So that Python can find the local copy of package.lib
.
I think this is a bad idea, as this line is only useful for developers or people running from a local copy, but I can't give a good reason why it is a bad idea.
Should we use PYTOHNPATH
, sys.path
, or is either fine?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果修改路径的唯一原因是开发人员在其工作树上工作,那么您应该使用安装工具来为您设置环境。 virtualenv 非常流行,如果您使用 setuptools,您只需运行 setup.pydevelopment 即可在当前的 Python 安装中半安装工作树。
If the only reason to modify the path is for developers working from their working tree, then you should use an installation tool to set up your environment for you. virtualenv is very popular, and if you are using setuptools, you can simply run
setup.py develop
to semi-install the working tree in your current Python installation.我讨厌 PYTHONPATH。我发现按用户(尤其是守护程序用户)进行设置并跟踪项目文件夹的移动非常脆弱且烦人。我更愿意在独立项目的调用脚本中设置 sys.path 。
然而 sys.path.append 并不是这样做的方法。您可以轻松获得重复项,并且它不会对
.pth
文件进行排序。更好(也更易读):site.addsitedir
。script.py
通常不是更合适的位置,因为它位于您想要在路径上可用的包内部。库模块当然不应该接触 sys.path 本身。相反,您通常会在包外部有一个 hashbanged 脚本,用于实例化和运行应用程序,并且在这个简单的包装器脚本中,您可以放置诸如sys.path
-frobbing 之类的部署详细信息。I hate PYTHONPATH. I find it brittle and annoying to set on a per-user basis (especially for daemon users) and keep track of as project folders move around. I would much rather set
sys.path
in the invoke scripts for standalone projects.However
sys.path.append
isn't the way to do it. You can easily get duplicates, and it doesn't sort out.pth
files. Better (and more readable):site.addsitedir
.And
script.py
wouldn't normally be the more appropriate place to do it, as it's inside the package you want to make available on the path. Library modules should certainly not be touchingsys.path
themselves. Instead, you'd normally have a hashbanged-script outside the package that you use to instantiate and run the app, and it's in this trivial wrapper script you'd put deployment details likesys.path
-frobbing.一般来说,我会考虑设置一个环境变量(如 PYTHONPATH)
这是一个不好的做法。虽然这对于一次性调试可能没问题,但将其用作
定期练习可能不是一个好主意。
使用环境变量会导致诸如“它对我有用”的情况,当某些
else 报告代码库中的问题。人们也可以进行同样的练习
测试环境也是如此,导致像测试运行良好的情况
特定的开发人员,但当有人启动测试时可能会失败。
In general I would consider setting up of an environment variable (like PYTHONPATH)
to be a bad practice. While this might be fine for a one off debugging but using this as
a regular practice might not be a good idea.
Usage of environment variable leads to situations like "it works for me" when some one
else reports problems in the code base. Also one might carry the same practice with the
test environment as well, leading to situations like the tests running fine for a
particular developer but probably failing when some one launches the tests.
除了已经提到的许多其他原因之外,您还可以指出硬编码
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
很脆弱,因为它假定了 script.py 的位置——只有当 script.py 位于 Project/package 中时它才有效。如果用户决定将 script.py 移动/复制/符号链接(几乎)到其他任何地方,它就会中断。
Along with the many other reasons mentioned already, you could also point outh that hard-coding
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
is brittle because it presumes the location of script.py -- it will only work if script.py is located in Project/package. It will break if a user decides to move/copy/symlink script.py (almost) anywhere else.
由于前面提到的原因,黑客攻击
PYTHONPATH
和sys.path
都不是一个好主意。为了将当前项目链接到 site-packages 文件夹,实际上有一种比 python setup.pydevelop 更好的方法,如 此处:pip install --editable path/to/project
如果您尚未进行设置.py 在项目的根文件夹中,这个足以开始:
Neither hacking
PYTHONPATH
norsys.path
is a good idea due to the before mentioned reasons. And for linking the current project into the site-packages folder there is actually a better way thanpython setup.py develop
, as explained here:pip install --editable path/to/project
If you don't already have a setup.py in your project's root folder, this one is good enough to start with:
我认为,在这种情况下使用 PYTHONPATH 是更好的事情,主要是因为它不会引入(有问题的)不必要的代码。
毕竟,如果你想到这一点,你的用户不需要那个
sys.path
东西,因为你的包将被安装到站点包中,因为你将使用包装系统。如果用户选择从“本地副本”(如您所说)运行,那么我观察到,通常的做法是声明,如果在站点包之外使用,则需要将该包手动添加到 PYTHONPATH 。
I think, that in this case using PYTHONPATH is a better thing, mostly because it doesn't introduce (questionable) unneccessary code.
After all, if you think of it, your user doesn't need that
sys.path
thing, because your package will get installed into site-packages, because you will be using a packaging system.If the user chooses to run from a "local copy", as you call it, then I've observed, that the usual practice is to state, that the package needs to be added to PYTHONPATH manually, if used outside the site-packages.