Можем ли мы пролить определенный свет на то, как работает упаковка и импорт python? - PullRequest
39 голосов
/ 19 апреля 2011

У меня была реальная возможность справиться с управлением модулями на python, и каждый раз это проблема: упаковка - это не то, что люди делают каждый день, и это становится бременем для обучения и бременем для запоминания, даже когда вына самом деле, так как это происходит один раз.

Я хотел бы собрать здесь полный обзор того, как импорт, управление пакетами и распространение работают в Python, так что этот вопрос станет окончательным объяснением всей магии, котораябывает под капотом.Хотя я понимаю общий уровень вопроса, эти вещи настолько переплетены, что любой сфокусированный ответ не решит основную проблему: понять, как все работает, что устарело, что является текущим, какие просто альтернативы для той же задачи, какиеПричуды.

Ниже приведен список ключевых слов, на которые следует ссылаться, но это всего лишь пример из множества.Там намного больше, и вы можете добавить дополнительные детали.

  • PyPI
  • setuptools / Distribute
  • distutils
  • egg
  • egg-link
  • pip
  • zipimport
  • site.py
  • site-пакеты
  • .pth файлы
  • virtualenv
  • обработка скомпилированных модулейв яйцах (с и без установки через easy_install)
  • использование get_data ()
  • pypm
  • bento
  • PEP 376
  • сырный магазин
  • преследуемый за яйца

Ссылка на другие ответы, вероятно, хорошая идея.Как я уже сказал, этот вопрос предназначен для общего обзора.

Ответы [ 4 ]

11 голосов
/ 28 апреля 2011

По большей части это попытка взглянуть на упаковку / дистрибуцию, а не на механику import. К сожалению, упаковка - это место, где Python предоставляет несколько способов сделать это. Я просто пытаюсь заставить мяч двигаться вперед, надеюсь, другие помогут заполнить то, что я пропустил, или укажут на ошибки.

Прежде всего, здесь есть некоторая грязная терминология. Каталог, содержащий файл __init__.py, является пакетом. Тем не менее, большинство из того, о чем мы здесь говорим, это конкретные версии пакетов, опубликованные в PyPI, одном из его зеркал, или в системе управления пакетами, специфичной для поставщика, такой как Debian Apt, Redhat's Yum, Fink, Macports, Homebrew или ActiveState.

Эти опубликованные пакеты - это то, что люди пытаются называть «Распределениями», пытаясь использовать «Пакет» только в качестве языковой конструкции Python. Вы можете увидеть некоторые из этого использования в PEP-376 PEP-376 .

Теперь ваш список ключевых слов относится к нескольким различным аспектам экосистемы Python:

Поиск и публикация дистрибутивов Python:

  • PyPI (он же магазин сыра)
  • Зеркала PyPI
  • Различные инструменты / системы управления пакетами: apt, yum, fink, macports, homebrew
  • pypm (альтернатива ActiveState PyPI)

Выше перечислены все сервисы, которые предоставляют место для публикации дистрибутивов Python в различных форматах. Некоторые, такие как зеркала PyPI и репозитории apt / yum, могут быть запущены на вашем локальном компьютере или в сети вашей компании, но люди обычно используют официальные. Большинство, если не все, предоставляют инструмент (или несколько инструментов в случае PyPI) для поиска и загрузки дистрибутивов.

Библиотеки, используемые для создания и установки дистрибутивов:

  • setuptools / Распределить
  • distutils

Distutils - это стандартная инфраструктура, в которой пакеты Python компилируются и встраиваются в дистрибутивы. В distutils есть тонна функциональности, но большинство людей просто знают:

from distutils.core import setup

setup(name='Distutils',
      version='1.0',
      description='Python Distribution Utilities',
      author='Greg Ward',
      author_email='gward@python.net',
      url='http://www.python.org/sigs/distutils-sig/',
      packages=['distutils', 'distutils.command'],
 )

И в некоторой степени это большая часть того, что вам нужно. В предыдущих 9 строках кода у вас достаточно информации для установки чистого пакета Python, а также минимальных метаданных, необходимых для публикации этого пакета в дистрибутиве PyPI.

Setuptools предоставляет ловушки, необходимые для поддержки формата Egg, а также всех его функций и возможностей. Распространение является альтернативой Setuptools, которая добавляет некоторые функции, пытаясь быть в основном обратно совместимыми. Я верю, что Distribute будет включен в Python 3 как преемник Distutil from distutils.core import setup.

И Setuptools, и Distribute предоставляют пользовательскую версию distutils команды установки это делает полезные вещи, такие как поддержка формата Egg.

Форматы распространения Python:

Дистрибутивы обычно предоставляются в виде исходных архивов (tarball или zipfile). Стандартный способ установки исходного дистрибутива - загрузить и распаковать архив, а затем запустить файл setup.py внутри.

Например, следующее загрузит, соберет и установит библиотеку подсветки синтаксиса Pygments:

curl -O -G http://pypi.python.org/packages/source/P/Pygments/Pygments-1.4.tar.gz
tar -zxvf Pygments-1.4.tar.gz
cd Pygments-1.4
python setup.py build
sudo python setup.py install

Также вы можете скачать файл Egg и установить его. Обычно это достигается с помощью easy_install или pip:

sudo easy_install pygments
or 
sudo pip install pygments

Яйца были вдохновлены Jarfiles Java, и у них есть довольно много функций, о которых вы должны прочитать здесь

Форматы пакетов Python:

  • несжатых каталогов
  • zipimport (сжатые zip-каталогами)

Обычный пакет python - это просто каталог, содержащий файл __init__.py и произвольное количество дополнительных модулей или подпакетов. Python также поддерживает поиск и загрузку исходного кода в файлах * .zip, если они включены в PYTHONPATH (sys.path).

Установка пакетов Python:

  • easy_install: оригинальный инструмент для установки яиц, зависит от setuptools
  • pip: в настоящее время самый популярный способ установки пакетов Python. Аналогичен easy_install, но более гибок и обладает некоторыми приятными функциями, такими как файлы требований, которые помогают документировать зависимости и воспроизводить развертывания.
  • pypm, apt, yum, fink и т. Д.

Управление средой / Автоматическое развертывание:

  • bento
  • buildout
  • virtualenvvirtualenvwrapper)

Вышеуказанные инструменты используются для автоматизации и управления зависимостями для проекта Python. По сути, они предоставляют вам инструменты для описания того, какие дистрибутивы требуются вашему приложению, и автоматизируют установку этих конкретных версий ваших зависимостей.

Расположение пакетов / дистрибутивов:

  • сайт-пакеты
  • PYTHONPATH
  • текущий рабочий каталог (зависит от вашей ОС и настроек среды)

По умолчанию при установке дистрибутива Python он помещается в каталог site-packages. Этот каталог обычно выглядит как /usr/lib/pythonX.Y/site-packages.

Простой программный способ найти каталог вашего сайта-пакетов:

from distuils import sysconfig
print sysconfig.get_python_lib()

Способы изменения вашего PYTHONPATH:

Оператор импорта Python найдет только те пакеты, которые находятся в одном из каталогов, включенных в PYTHONPATH.

Вы можете проверить и изменить свой путь из Python, выполнив:

import sys
print sys.path
sys.path.append("/home/myname/lib")

Кроме того, вы можете установить переменную окружения PYTHONPATH так же, как любую другую переменную среды в вашей ОС, или вы можете использовать:

  • .pth файлы: * .pth файлы, расположенные в каталогах, которые уже находятся в вашем PYTHONPATH, читаются, и каждая строка * .pth файла добавляется в ваш PYTHONPATH. По сути, в любое время, когда вы копируете пакет в каталог на PYTHONPATH, вы можете вместо этого создать mypackages.pth. Подробнее о * .pth файлах: модуль сайта
  • файлы яичных ссылок: внутренняя структура яиц питона они являются кроссплатформенной альтернативой символическим ссылкам. Создание файла ссылки на яйцо аналогично созданию файла pth.
  • site.py модификации

Чтобы добавить вышеупомянутые /home/myname/lib к пакетам сайта с файлом * .pth, вы должны создать файл * .pth. Название файла не имеет значения, но вы все равно должны выбрать что-нибудь разумное.

Давайте создадим myname.pth:

# myname.pth
/home/myname/lib

Вот и все. Перетащите это в sysconfig.get_python_lib() в вашей системе или в любой другой каталог в вашем PYTHONPATH, и /home/myname/lib будет добавлен в путь.

3 голосов
/ 20 апреля 2011

Для вопроса об упаковке это должно помочь http://guide.python -distribute.org /

Для импорта старая статья от Фредрика Лунда http://effbot.org/zone/import-confusion.htm по-прежнему очень хорошая отправная точка.

2 голосов
/ 28 апреля 2011

Я рекомендую Книга Тарека Зиадека по Python. Есть глава, посвященная упаковке и распространению.

0 голосов
/ 27 апреля 2011

Я не думаю, что нужно исследовать import (функциональность пространства имен и импорта в Python интуитивно понятна).

Я использую pip исключительно сейчас.Я не сталкивался с какими-либо проблемами.

Тем не менее, тема упаковки и распространения заслуживает изучения.Вместо длинного ответа я скажу следующее:

Я научился упаковывать и распространять свои «пакеты», просто копируя, как это делают Pylons или многие другие пакеты с открытым исходным кодом.Затем я скомбинировал этот тип шаблона с чтением документов, чтобы еще более уточнить его, и придумал твердый метод распространения.это на самом деле довольно мощный.Мне это очень нравится.

[edit]

Я также хотел бы добавить немного о virtualenv.ИСПОЛЬЗУЙ ЭТО.Я создаю virtualenv для каждого проекта и всегда использую --no-site-packages;Я устанавливаю все пакеты, которые мне нужны для этого конкретного проекта (даже если среди них есть что-то общее, например lxml) внутри virtualev.Он хранит все в изоляции, и мне намного легче поддерживать группировку в моей голове (вместо того, чтобы пытаться отслеживать, где и для какой версии Python!)

[/ edit]

...