Подтвердить что ты не робот

Как Python отслеживает модули, установленные с яйцами?

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

4b9b3361

Ответ 1

Если вы используете easy_install script, предоставленный setuptools (или его Distribute) для установки пакетов как яйца, вы увидите, что по умолчанию он создает файл с именем easy-install.pth в каталоге site-packages вашей установки Python. Файлы конфигурации пути являются стандартной функцией Python:

Файл конфигурации пути - это файл чье имя имеет форму package.pth и существует в одном из четырех упомянутые выше каталоги; его содержимое - дополнительные предметы (по одному в line) для добавления в sys.path.

easy_install сильно использует эту функцию Python. Когда вы используете easy_install для добавления или обновления дистрибутива, он изменяет easy-install.pth, чтобы добавить каталог яиц или 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 для установки дистрибутива в виде нескольких версий, запись easy-install.pth для него не добавляется или удаляется, если она уже существует. Вот почему easy_install документация сообщает вам использовать -m перед удалением установленного яйца.

Ответ 2

Когда вы запускаете easy_install, он копирует яйцо в пакеты-сайты и помещает путь к этому яйцу в вашу переменную 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 ​​непосредственно в пакеты сайта.