12

如果我有一个模块,foo, in Lib/site-packages,我可以import foo并且它会工作。但是,当我从 egg 安装东西时,我得到了blah-4.0.1-py2.7-win32.egg一个文件夹,里面有模块内容,但我仍然只需要 do import foo,而不是更复杂的东西。Python如何跟踪鸡蛋?这不仅仅是 dirname 匹配,就好像我将该文件夹放入 Python 安装而不通过 dist-utils,它没有找到该模块。

更清楚一点:我刚刚安装了 zope。文件夹名称为“zope.interface-3.3.0-py2.7-win32.egg”。这有效:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import zope.interface
>>>

我创建了一个“blah-4.0.1-py2.7-win32.egg”文件夹,其中包含一个空模块“haha”(和__init__.py)。这不起作用:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import blah.haha
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named blah.haha
>>>

但是,这样做:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pkg_resources import require
>>> require("blah>=1.0")
[blah 4.0.1 (c:\python27\lib\site-packages\blah-4.0.1-py2.7-win32.egg)]
>>> import haha
>>>

那么如何在没有 的情况下使其工作require

4

2 回答 2

19

如果您使用easy_installsetuptools(或Distribute它的分支)提供的脚本将包安装为鸡蛋,您将看到默认情况下,它会在您的 Python 安装目录中 创建一个名为easy-install.pth的文件。路径配置文件是 Python 的标准特性:site-packages

路径配置文件是名称格式为 package.pth 且存在于上述四个目录之一中的文件;它的内容是要添加到 sys.path 的附加项目(每行一个)。

easy_install大量使用了这个 Python 特性。当您用于easy_install添加或更新一个发行版时,它会修改easy-install.pth为添加 egg 目录或 zip 文件。通过这种方式,easy_install保持对模块搜索顺序的控制,并确保它安装的鸡蛋出现在搜索顺序的早期。以下是 an 内容的示例easy-install.pth

import sys; sys.__plen = len(sys.path)
./appscript-0.21.1-py2.6-macosx-10.5-ppc.egg
./yolk-0.4.1-py2.6.egg
./Elixir-0.7.1-py2.6.egg
./Fabric-0.9.0-py2.6.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginse
rt',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)

正如您在此处所看到的,如果您检查其中的代码setuptools,您会发现它采用了一些技巧来引导自身,然后掩盖其轨迹,这会使调试问题site.py和解释器启动变得有点有趣。(这也是一些开发者不喜欢使用它的原因之一。)

如果您使用-m参数 ofeasy_install将发行版安装为multi-versioneasy-install.pth则不会添加它的条目,如果它已经存在则将其删除。这就是为什么easy_install文档告诉您-m在删除已安装的 egg 之前使用。

于 2010-11-29T18:53:18.503 回答
3

当您运行 easy_install 时,它会将 egg 复制到 site-packages 中,并将该 egg 的路径放在您的 sys.path 变量中。(请注意, sys.path 不是您的 PATH 环境变量,它是由 PYTHONPATH 和其他环境变量构造的。因此,您使用 easy_install 安装的 .egg 文件被放入某个环境变量中,python 知道当python解释器启动)。

要让 blah.haha 在您的示例中工作,可以运行easy_install blah-4.0.1-py2.7-win32.egg然后您可以import haha从 python 中运行,或者直接将 haha​​ 模块放在站点包中。

于 2010-11-29T16:52:59.510 回答