Как Python отслеживает модули, установленные с яйцами? - PullRequest
12 голосов
/ 29 ноября 2010

Если у меня есть модуль foo в Lib/site-packages, я могу просто import foo, и он будет работать.Однако, когда я устанавливаю вещи из яиц, я получаю что-то вроде blah-4.0.1-py2.7-win32.egg в виде папки с содержимым модуля внутри, но мне все еще нужно только сделать import foo, а не что-нибудь более сложное.Как Python отслеживает яйца?Это не просто поиск по имени, как если бы я перетаскивал эту папку в установку 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» с пустым модулем «хаха» (и __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?

Ответы [ 2 ]

19 голосов
/ 29 ноября 2010

Если вы используете скрипт easy_install, предоставляемый setuptools (или его Distribute) для установки пакетов в виде яиц, вы увидите, что по умолчанию он создает файл с именем easy-install.pth вsite-packages каталог вашей установки Python. Файлы конфигурации пути - это стандартная функция 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 и запуска интерпретатора немного интересными .(Это одна из причин того, что некоторые разработчики не любят его использовать.)

Если вы используете параметр -m easy_install для установки дистрибутива как multi-version запись easy-install.pth для него не добавляется или удаляется, если она уже существует.Вот почему документация easy_install говорит вам использовать -m перед удалением установленного яйца.

3 голосов
/ 29 ноября 2010

Когда вы запускаете easy_install, он копирует яйцо в site-packages и помещает путь к этому яйцу в вашу переменную sys.path. (Обратите внимание, что sys.path не является переменной окружения PATH, она создана из PYTHONPATH и других переменных окружения. Поэтому файл .egg, который вы устанавливаете с помощью easy_install, помещается в некоторую переменную окружения, и python знает, как добавить его в sys.path, запускается интерпретатор python).

Чтобы заставить blah.haha работать в вашем примере, либо запустите easy_install blah-4.0.1-py2.7-win32.egg, а затем вы можете import haha изнутри python, либо просто поместите модуль haha ​​непосредственно в site-packages.

...