PYTHONPATH 环境变量之前的路径中的鸡蛋

发布于 2024-11-07 02:01:29 字数 408 浏览 1 评论 0原文

如果我从 easy_install 安装了软件包,则 Egg 会被添加到 PYTHONPATH 变量中的项目之前的 sys.path 中。

例如,如果我在当前目录中安装了一个名为 foo 的 Egg 包以及一个名为 foo 的包,然后执行以下操作:

PYTHONPATH="." python
>>> import foo

这将使用 Egg 版本foo 而不是本地目录。检查sys.path显示鸡蛋被放置在PYTHONPATH中的之前项目。这似乎坏了。有什么办法可以覆盖这种行为吗?

If I have packages installed from easy_install, the eggs are prepended to sys.path before the items in the PYTHONPATH variable.

For example, if I have an egg package called foo installed as well as a package called foo in the current directory, and then do this:

PYTHONPATH="." python
>>> import foo

This will use the egg version of foo instead of the local directory. Inspecting sys.path shows that eggs are placed before items from PYTHONPATH. This seems broken. Is there any way to override this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

惜醉颜 2024-11-14 02:01:29

不幸的是,这是通过 setuptools/command/easy_install.py 内部的硬编码模板完成的。您可以使用编辑后的模板创建一个修补的 setuptools,但我没有找到从外部扩展 easy_install 的干净方法。

每次 easy_install 运行时都会重新生成文件 easy_install.pth。这是一个快速脚本,您可以在 easy_install 之后运行它,以从 easy_install.pth 中删除页眉和页脚。您可以创建一个包装器 shell 脚本,以便在 easy_install 之后立即运行它:

#!/usr/bin/env python
import sys
path = sys.argv[1]
lines = open(path, 'rb').readlines()
if lines and 'import sys' in lines[0]:
    open(path, 'wb').write(''.join(lines[1:-1]) + '\n')

示例:

% easy_install gdata
% PYTHONPATH=xyz python -c 'import sys; print sys.path[:2]'
['', '/Users/pat/virt/lib/python2.6/site-packages/gdata-2.0.14-py2.6.egg']

% ./fix_path ~/virt/lib/python2.6/site-packages/easy_install.pth
% PYTHONPATH=xyz python -c 'import sys; print sys.path[:2]'
['', '/Users/pat/xyz']

为了获得更多说明,以下是 easy-install.pth 的格式:

import sys; sys.__plen = len(sys.path)
./gdata-2.0.14-py2.6.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)

两个 import sys 行是导致鸡蛋出现在路径开头的罪魁祸首。我的脚本只是删除了那些 sys.path-munging 行。

Unfortunately this is done with a hard-coded template deep inside setuptools/command/easy_install.py. You could create a patched setuptools with an edited template, but I've found no clean way to extend easy_install from the outside.

Each time easy_install runs it will regenerate the file easy_install.pth. Here is a quick script which you can run after easy_install, to remove the header and footer from easy_install.pth. You could create a wrapper shell script to run this immediately after easy_install:

#!/usr/bin/env python
import sys
path = sys.argv[1]
lines = open(path, 'rb').readlines()
if lines and 'import sys' in lines[0]:
    open(path, 'wb').write(''.join(lines[1:-1]) + '\n')

Example:

% easy_install gdata
% PYTHONPATH=xyz python -c 'import sys; print sys.path[:2]'
['', '/Users/pat/virt/lib/python2.6/site-packages/gdata-2.0.14-py2.6.egg']

% ./fix_path ~/virt/lib/python2.6/site-packages/easy_install.pth
% PYTHONPATH=xyz python -c 'import sys; print sys.path[:2]'
['', '/Users/pat/xyz']

For more clarification, here is the format of easy-install.pth:

import sys; sys.__plen = len(sys.path)
./gdata-2.0.14-py2.6.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)

The two import sys lines are the culprit causing the eggs to appear at the start of the path. My script just removes those sys.path-munging lines.

春庭雪 2024-11-14 02:01:29

考虑使用 -S 命令行选项来抑制 *.pth 处理:

python -c 'import sys; print("\n".join(sys.path))'
python -S -c 'import sys; print("\n".join(sys.path))'

https://docs.python.org/3/library/site.html#site.main

您还可以使用 -S 和 site.main() 来延迟*.pth 处理直到运行时,例如捕获原始 sys.path 进行附加:

export PYTHONPATH=$(
  PYTHONPATH='' \
  python -c 'import sys; \
    sys.path.extend(sys.argv[1:]); old=list(sys.path); \
    import site; site.main(); \
    [ old.append(p) for p in sys.path if p not in old ]; \
    sys.path=old; \
    print ":".join(sys.path)' \
  $EXTRA_PATH $ANOTHER_PATH)

python -S ... # using explicit PYTHONPATH
  • 从显式空 PYTHONPATH 开始,
  • 使用扩展显式附加到 sys.path
  • 导入站点并调用 < code>site.main()
  • 将新路径追加到旧路径,然后将其安装到 sys.path 中
  • 使用“:”打印 PYTHONPATH
  • python -S 是适合稍后运行仅使用$PYTHONPATH
  • python -S 在设置 PYTHONPATH 时可能需要也可能不需要(取决于您是否需要在扩展之前扩展 sys.path)

Consider using the -S command-line option to suppress *.pth processing:

python -c 'import sys; print("\n".join(sys.path))'
python -S -c 'import sys; print("\n".join(sys.path))'

https://docs.python.org/3/library/site.html#site.main

You can also use -S with site.main() to delay *.pth processing until runtime, say to capture the original sys.path for appending:

export PYTHONPATH=$(
  PYTHONPATH='' \
  python -c 'import sys; \
    sys.path.extend(sys.argv[1:]); old=list(sys.path); \
    import site; site.main(); \
    [ old.append(p) for p in sys.path if p not in old ]; \
    sys.path=old; \
    print ":".join(sys.path)' \
  $EXTRA_PATH $ANOTHER_PATH)

python -S ... # using explicit PYTHONPATH
  • Start from explicit empty PYTHONPATH
  • Append to sys.path explicitly with extend
  • Import site and call site.main()
  • Append new paths to old path and then install it in sys.path
  • Print with ":" for PYTHONPATH
  • python -S is desirable for later runs only using $PYTHONPATH
  • python -S may or may not be desirable while setting PYTHONPATH (depending on if you need sys.path expanded before extending)
花开柳相依 2024-11-14 02:01:29

在运行顶级 python 可执行文件时,我做了类似以下的事情来添加到系统路径:

import sys
sys.path = ["<your python path>"] + sys.path

通常,对我来说 "" 涉及使用 __file__ 属性来相对查找包含我的项目的顶级模块的路径。不建议将其用于生产鸡蛋,尽管我似乎并不介意后果。可能还有另一种替代 __file__ 的方法。

I have done something like the following to prepend to the system path when running a top-level python executable file:

import sys
sys.path = ["<your python path>"] + sys.path

Often, the "<your python path>" for me involves use of the __file__ attribute to do relative look up for a path that includes the top-level module for my project. This is not recommended for use in producing, eggs, though I don't seem to mind the consequences. There may be another alternative to __file__.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文