2010-11-29 53 views
11

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

更清晰:我刚安装了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 
>>> 

我创建了一个 “嗒嗒-4.0.1-py2.7-win32.egg” 文件夹中的一个空模块 “哈哈”(和__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工作?

+0

Python源代码完全为您提供。你可以阅读`import`语句的实现,而不会有太多的麻烦。正如他们所说:“使用源泉,卢克。” – 2010-11-29 16:33:54

回答

18

如果您使用setuptools提供的easy_install脚本(或Distribute叉的话)来安装软件包如鸡蛋,你会看到,默认情况下,它会创建一个在site-packages目录Python安装的命名easy-install.pth文件。 Path configuration files是Python中的标准特性:

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

easy_install大量使用此Python功能。当您使用easy_install添加或更新分配时,它会修改easy-install.pth以添加egg目录或zip文件。通过这种方式,easy_install可以保持对模块搜索顺序的控制,并确保它安装的鸡蛋早在搜索顺序中出现。这里是一个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和解释器启动有趣调试问题。 (这是一些开发人员不喜欢使用它的原因之一。)

如果您使用的easy_install-m参数安装一个分发多版本,在easy-install.pth条目它不添加或如果它已经存在被删除。这就是为什么easy_install documentation告诉你在删除安装的蛋之前使用-m

3

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

为了让blah.haha在你的例子中工作,可以运行easy_install blah-4.0.1-py2.7-win32.egg,然后你可以在python中使用import haha,或者直接把haha模块直接放在site-packages中。