Почему лучше использовать Poetry вместо Pip или Conda для проектов Python
Сравнение инструментов управления зависимостями (dependency management) в Python.
Статья является переводом поста в blogs.sap.com: Why you should use Poetry instead of Pip or Conda for Python Projects.
Управление зависимостями – важная составляющая любого проекта, которая требует использования внешних библиотек и пакетов (тех, что не входят в программную среду по умолчанию). Ряд приложений, разрабатываемых с помощью Python, является примером такого использования. Существует множество внешних инструментов для управления зависимостями в Python-проектах, такие как Pip, Conda и даже Poetry. Понимая, что у каждого разработчика есть свои предпочтения, я бы хотел поделиться больше тем, почему иногда может быть лучше использовать Poetry, а не Pip или Conda. Данные инструменты рассматриваются в этой статье потому, что я имею непосредственный опыт работы с каждым из них.
Для начала
Прежде чем мы двинемся дальше, думаю, было бы полезным поговорить немного подробнее об инструментах управления зависимостями, которые мы будем сравнивать:
- Conda – это инструмент управления зависимостями, пришедший из Anaconda. Последняя обычно используется в data science теми, кто только начинает работу с Python и не хочет сильно утруждаться с установкой общих зависимостей (dependencies), необходимых в данной сфере: numpy, pandas, jupiter и scikit-learn. Больше информации о Conda можно найти в документации и на официальной странице Anaconda.
- Pip – инструмент управления зависимостями, пришедший из стандартных настроек Python для Windows. Он может быть установлен через Homebrew для MacOS или менеджер пакетов для Linux (например, APT для Debian и Ubuntru). В этой статье дается вполне хорошее описание того, как можно начать работу с Pip.
- Poetry – новый инструмент управления зависимостями, который набирает популярность среди пользователей Python. Использование файлов pypoproject.toml и poetry.lock делает его похожим на Node Package Manager (npm) для Node.js. Более подробную информацию про Poetry можно найти в документации.
Интересная часть
Вот теперь я попытаюсь убедить вас, что Poetry – лучший выбор из всех трёх инструментов, что описаны выше.
Избегайте Conda повсюду, где вы собираетесь использовать Python в продуктиве.
Я знаю, "избегайте x повсюду" – достаточно сильная фраза в данном контексте, но у меня есть причины говорить так.
Предустановленные пакеты в Anaconda
Если мы запустим команду conda list в базовом окружении, мы можем увидеть нечто такое:
(base) user:~$ conda list # packages in environment at /home/user/anaconda3: # # Name Version Build Channel _ipyw_jlab_nb_ext_conf 0.1.0 py39h06a4308_0 _libgcc_mutex 0.1 main _openmp_mutex 4.5 1_gnu alabaster 0.7.12 pyhd3eb1b0_0 ... jupyter 1.0.0 py39h06a4308_7 ... numpy 1.20.3 py39hf144106_0 ... pandas 1.3.4 py39h8c16a72_0 ... scikit-learn 0.24.2 py39ha9443f7_0 ...
Это имеет смысл для тех, кто только приступил к изучению Python в data science и пока не хочет тратить слишком много времени на попытки определить, как вывести все зависимости, которые им нужны. Однако, когда дело касается реального проекта, мы обычно не хотим загружать пакеты, которые нам не слишком-то и нужны. Их наличие только заполняет память и пространство системы, которые можно было бы использовать для чего-то более важного. Конечно, существует также Miniconda, которая использует базу Conda без всех этих дополнительных пакетов, но...
Ненужные пакеты добавляются во время установки
Например, если мы запустим команду conda install -c conda-forge numpy==1.22.3, мы увидим следующее:
The following NEW packages will be INSTALLED: _libgcc_mutex conda-forge/linux-64::_libgcc_mutex-0.1-conda_forge _openmp_mutex conda-forge/linux-64::_openmp_mutex-4.5-1_gnu bzip2 conda-forge/linux-64::bzip2-1.0.8-h7f98852_4 ca-certificates conda-forge/linux-64::ca-certificates-2021.10.8-ha878542_0 ld_impl_linux-64 conda-forge/linux-64::ld_impl_linux-64-2.36.1-hea4e1c9_2 libblas conda-forge/linux-64::libblas-3.9.0-14_linux64_openblas libcblas conda-forge/linux-64::libcblas-3.9.0-14_linux64_openblas libffi conda-forge/linux-64::libffi-3.4.2-h7f98852_5 libgcc-ng conda-forge/linux-64::libgcc-ng-11.2.0-h1d223b6_15 libgfortran-ng conda-forge/linux-64::libgfortran-ng-11.2.0-h69a702a_15 libgfortran5 conda-forge/linux-64::libgfortran5-11.2.0-h5c6108e_15 libgomp conda-forge/linux-64::libgomp-11.2.0-h1d223b6_15 liblapack conda-forge/linux-64::liblapack-3.9.0-14_linux64_openblas libnsl conda-forge/linux-64::libnsl-2.0.0-h7f98852_0 libopenblas conda-forge/linux-64::libopenblas-0.3.20-pthreads_h78a6416_0 libstdcxx-ng conda-forge/linux-64::libstdcxx-ng-11.2.0-he4da1e4_15 libuuid conda-forge/linux-64::libuuid-2.32.1-h7f98852_1000 libzlib conda-forge/linux-64::libzlib-1.2.11-h166bdaf_1014 ncurses conda-forge/linux-64::ncurses-6.3-h27087fc_1 numpy conda-forge/linux-64::numpy-1.22.3-py310h45f3432_2 openssl conda-forge/linux-64::openssl-3.0.2-h166bdaf_1 pip conda-forge/noarch::pip-22.0.4-pyhd8ed1ab_0 python conda-forge/linux-64::python-3.10.4-h2660328_0_cpython python_abi conda-forge/linux-64::python_abi-3.10-2_cp310 readline conda-forge/linux-64::readline-8.1-h46c0cb4_0 setuptools conda-forge/linux-64::setuptools-62.1.0-py310hff52083_0 sqlite conda-forge/linux-64::sqlite-3.38.2-h4ff8645_0 tk conda-forge/linux-64::tk-8.6.12-h27826a3_0 tzdata conda-forge/noarch::tzdata-2022a-h191b570_0 wheel conda-forge/noarch::wheel-0.37.1-pyhd8ed1ab_0 xz conda-forge/linux-64::xz-5.2.5-h516909a_1 zlib conda-forge/linux-64::zlib-1.2.11-h166bdaf_1014
Я вполне уверен, что библиотеки типа ca-certificates and openssl не слишком нужны при numpy, но давайте посмотрим, что мы получим, когда попытаемся установить numpy в новое виртуальное окружение, используя вместо этого Pip. Я также запущу команду pip list, чтобы увидеть какие пакеты установятся вместе с numpy:
user:~$ pip install numpy==1.22.3 Collecting numpy==1.22.3 Downloading numpy-1.22.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.8 MB) |████████████████████████████████| 16.8 MB 10.2 MB/s Installing collected packages: numpy Successfully installed numpy-1.22.3 user:~$ pip list Package Version ---------- ------- numpy 1.22.3 pip 21.2.2 setuptools 57.4.0 wheel 0.36.2
Ух ты, это даже близко не стоит к тому количеству пакетов Conda, которые были предложены, когда мы устанавливали numpy с помощью неё. Такая "раздутость" является серьезной причиной отказаться от Conda в управлении зависимостями в продуктиве.
Странное поведение при отображении установленных зависимостей
Например, если я установлю numpy с помощью Pip в новое виртуальное окружение Conda, я увижу что-то вроде этого:
(test-env) user:~$ conda list # packages in environment at /home/user/anaconda3/envs/test-env: # # Name Version Build Channel (test-env) user:~$ pip list Package Version ---------- ------- numpy 1.22.3 pip 21.2.2 setuptools 57.4.0 wheel 0.36.2
Хм, странно. numpy не показывается, когда мы запускаем команду conda list, но всплывает, когда мы запускаем pip list command.
Но это не всё. Если я сейчас установлю pandas через conda-forge, мы увидим что-то похожее на то, что мы получили, когда запускали conda list и pip list commands:
(test-env) user:~$ conda list # packages in environment at /home/user/anaconda3/envs/test-env: # # Name Version Build Channel ... numpy 1.22.3 pypi_0 pypi ... pandas 1.4.2 pypi_0 pypi ... (test-env) user:~$ pip list Package Version --------------- ------- numpy 1.22.3 pandas 1.4.2 ...
Похоже, что пакеты, установленные через Pip, показываются в выводе conda list, если другой пакет, использующий их, был установлен через conda-forge. Это может сбивать с толку пользователей, так как:
1. Нам нужно использовать две разные команды, чтобы проверить все наши зависимости.
2. Мы можем пропустить некоторые зависимости, если используем только conda list, чтобы проверить их.
Я надеюсь, что эти доводы достаточно красноречивы, чтобы вы поняли, почему лучше вообще отказаться от использования Conda, если мы планируем делать какую-то серьёзную работу. Поняв, что точно нужно исключить, сосредоточимся теперь на сравнении Poetry и Pip.
Почему же тогда на Pip?
Я понимаю, что существуют люди, которые предпочитают использовать Pip по вполне резонным причинам. Например, Pip существует дольше, чем Poetry, а люди склонны придерживаться своих привычек. Тем не менее, я бы хотел поделиться некоторыми наблюдениями и всё-таки убедить вас в том, что Poetry в данном случае – лучший выбор.
Более эффективная работа с конфликтами
Для примера давайте посмотрим, что происходит, когда мы используем Pip, чтобы установить различные версии numpy в виртуальное окружение, в котором уже установлена pandas:
(test-env) user:~$ pip list Package Version --------------- ------- numpy 1.22.3 pandas 1.4.2 pip 21.1.1 python-dateutil 2.8.2 pytz 2022.1 setuptools 56.0.0 six 1.16.0 (test-env) user:~$ pip install "numpy<1.18.5" Collecting numpy<1.18.5 Downloading numpy-1.18.4-cp38-cp38-manylinux1_x86_64.whl (20.7 MB) |████████████████████████████████| 20.7 MB 10.9 MB/s Installing collected packages: numpy Attempting uninstall: numpy Found existing installation: numpy 1.22.3 Uninstalling numpy-1.22.3: Successfully uninstalled numpy-1.22.3 ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. pandas 1.4.2 requires numpy>=1.18.5; platform_machine != "aarch64" and platform_machine != "arm64" and python_version < "3.10", but you have numpy 1.18.4 which is incompatible. Successfully installed numpy-1.18.4 (test-env) user:~$ pip list Package Version --------------- ------- numpy 1.18.4 pandas 1.4.2 pip 21.1.1 python-dateutil 2.8.2 pytz 2022.1 setuptools 56.0.0 six
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти