- Lee On Coding
- How does python find packages?
- sys.path
- How sys.path gets populated
- You can manipulate sys.path
- The module __file__ attribute
- The imp module
- Ubuntu Python
- Ubuntu Python ( /usr/bin/python ):
- Python compiled from source ( /usr/local/bin/python )
- How did Ubuntu manipulate the sys.path ?
- Решение проблем с модулями и пакетами Python
- Отсутствие модуля Python
- Пакет Python установлен, но программа его не видит
- Установлена новая версия модуля, но программа видит старую версию
- Ошибки с фразой «AttributeError: ‘NoneType’ object has no attribute»
- Модуль установлен, но при обновлении или обращении к нему появляется ошибки
- Заключение
- Python. Урок 16. Установка пакетов в Python
- Где взять отсутствующий пакет?
- Менеджер пакетов в Python – pip
- Установка pip
- Обновление pip
- Использование pip
- Установка пакета
- Удаление пакета
- Обновление пакетов
- Просмотр установленных пакетов
- Поиск пакета в репозитории
- Где ещё можно прочитать про работу с pip?
- P.S.
Lee On Coding
My blog about coding and stuff.
How does python find packages?
I just ran into a situation where I compiled and installed Python 2.7.9 from source on Ubuntu, but Python could not find the packages I had previously installed. This naturally raises the question — how does Python know where to find packages when you call import ? This post applies specifically to Python 2.7.9, but I’m guessing Python 3x works very similarly.
In this post I first describe how Python finds packages, and then I’ll finish with the discovery I made regarding the default Python that ships with Ubuntu and how it differs from vanilla Python in how it finds packages.
sys.path
Python imports work by searching the directories listed in sys.path .
Using my default Ubuntu 14.04 Python:
So Python will find any packages that have been installed to those locations.
How sys.path gets populated
As the docs explain, sys.path is populated using the current working directory, followed by directories listed in your PYTHONPATH environment variable, followed by installation-dependent default paths, which are controlled by the site module.
You can read more about sys.path in the Python docs.
Assuming your PYTHONPATH environment variable is not set, sys.path will consist of the current working directory plus any manipulations made to it by the site module.
The site module is automatically imported when you start Python, you can read more about how it manipulates your sys.path in the Python docs.
It’s a bit involved.
You can manipulate sys.path
You can manipulate sys.path during a Python session and this will change how Python finds modules. For example:
The module __file__ attribute
When you import a module, you usually can check the __file__ attribute of the module to see where the module is in your filesystem:
However, the Python docs state that:
The file attribute is not present for C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file.
So, for example this doesn’t work:
It makes sense that the sys module is statically linked to the interpreter — it is essentially part of the interpreter!
The imp module
Python exposes the entire import system through the imp module. That’s pretty cool that all of this stuff is exposed for us to abuse, if we wanted to.
imp.find_module can be used to find a module:
You can also import and arbitrary Python source as a module using imp.load_source . This is the same example before, except imports our module using imp instead of by manipulating sys.path :
Passing ‘hi’ to imp.load_source simply sets the __name__ attribute of the module.
Ubuntu Python
Now back to the issue of missing packages after installing a new version of Python compiled from source. By comparing the sys.path from both the Ubuntu Python, which resides at /usr/bin/python , and the newly installed Python, which resides at /usr/local/bin/python , I could sort things out:
Ubuntu Python ( /usr/bin/python ):
Python compiled from source ( /usr/local/bin/python )
Turns out what mattered for me was dist-packages vs. site-packages . Using Ubuntu’s Python, my packages were installed to /usr/local/lib/python2.7/dist-packages , whereas the new Python I installed expects packages to be installed to /usr/local/lib/python2.7/site-packages . I just had to manipulate the PYTHONPATH environment variable to point to dist-packages in order to gain access to the previously installed packaged with the newly installed version of Python.
How did Ubuntu manipulate the sys.path ?
So how does the Ubuntu distribution of Python know to use /usr/local/lib/python2.7/dist-packages in sys.path ? It’s hardcoded into their site module! First, find where the site module code lives:
Here is an excerpt from Ubuntu Python’s site.py , which I peeked by opening /usr/lib/python2.7/site.py in a text editor. First, a comment at the top:
For Debian and derivatives, this sys.path is augmented with directories for packages distributed within the distribution. Local addons go into /usr/local/lib/python /dist-packages, Debian addons install into /usr/
/python /dist-packages. /usr/lib/python /site-packages is not used.
OK so there you have it. They explain how the Debian distribution of Python is different.
And now, for the code that implementes this change:
It’s all there, if you are crazy enough to dig this deep.
© Lee Mendelowitz – Built with Pure Theme for Pelican
Решение проблем с модулями и пакетами Python
Я с завидной регулярностью сталкиваюсь со всевозможными ошибками, так или иначе связанными с модулями Python. Существует огромное количество разнообразных модулей Python, которые разработчики активно используют, но далеко не всегда заботятся об установке зависимостей. Некоторые даже не удосуживаются их документировать. Параллельно существует две мажорные версии Python: 2 и 3. В разных дистрибутивах отдано предпочтение одной или другой версии, по этой причине самостоятельно установленную программу в зависимости от дистрибутива нужно при запуске предварять python или python2/python3. Например:
Причём обычно не происходит никаких проверок и угадали ли вы с выбором версии или нет вы узнаете только при появлении первых ошибок, вызванных неправильным синтаксисом программного кода для данной версии.
Также прибавляет путаницу то, что модули можно установить как из стандартного репозитория дистрибутивов, так и с помощью pip (инструмент для установки пакетов Python).
Цель этой заметки — рассмотреть некоторые характерные проблемы модулей Python. Все возможные ошибки вряд ли удастся охватить, но описанное здесь должно помочь понять, в каком примерно направлении двигаться.
Отсутствие модуля Python
Большинство ошибок модулей Python начинаются со строк:
В них трудно разобраться, поэтому поищите фразы вида:
- ModuleNotFoundError: No module named
- No module named
- ImportError: No module named
За ними следует название модуля.
Поищите по указанному имени в системном репозитории, или попробуйте установить командой вида:
Пакет Python установлен, но программа его не видит
Причина может быть в том, что вы установили модуль для другой версии. Например, программа написана на Python3, а вы установили модуль с этим же названием, но написанный на Python2. В этом случае он не будет существовать для программы. Поэтому нужно правильно указывать номер версии.
Команда pip также имеет свои две версии: pip2 и pip3. Если версия не указана, то это означает, что используется какая-то из двух указанных (2 или 3) версий, которая является основной в системе. Например, сейчас в Debian и производных по умолчанию основной версией Python является вторая. Поэтому в репозитории есть два пакета: python-pip (вторая версия) и python3-pip (третья).
В Arch Linux и производных по умолчанию основной версией является третья, поэтому в репозиториях присутствует пакет python-pip (третья версия) и python2-pip (вторая).
Это же самое относится к пакетам Python и самому Python: если версия не указана, значит имеется ввиду основная для вашего дистрибутива версия. По этой причине многие пакеты в репозитории присутствуют с двумя очень похожими названиями.
Установлена новая версия модуля, но программа видит старую версию
Я несколько раз сталкивался с подобными необъяснимыми ошибками.
Иногда помогает удаление модуля командой вида:
Также попробуйте удалить его используя системный менеджер пакетов.
Если модуль вам нужен, попробуйте вновь установить его и проверьте, решило ли это проблему.
Если проблема не решена, то удалите все файлы модуля, обычно они расположены в папках вида:
Ошибки с фразой «AttributeError: ‘NoneType’ object has no attribute»
Ошибки, в которых присутствует слово AttributeError, NoneType, object has no attribute обычно вызваны не отсутствием модуля, а тем, что модуль не получил ожидаемого аргумента, либо получил неправильное число аргументов. Было бы правильнее сказать, что ошибка вызвана недостаточной проверкой данных и отсутствием перехвата исключений (то есть программа плохо написана).
В этих случаях обычно ничего не требуется дополнительно устанавливать. В моей практике частыми случаями таких ошибок является обращение программы к определённому сайту, но сайт может быть недоступен, либо API ключ больше недействителен, либо программа не получила ожидаемые данные по другим причинам. Также программа может обращаться к другой программе, но из-за ошибки в ней получит не тот результат, который ожидала, и уже это вызывает приведённые выше ошибки, которые мы видим.
Опять же, хорошо написанная программа в этом случае должна вернуть что-то вроде «информация не загружена», «работа программы N завершилась ошибкой» и так далее. Как правило, нужно разбираться с причиной самой первой проблемы или обращаться к разработчику.
Модуль установлен, но при обновлении или обращении к нему появляется ошибки
Это самая экзотическая ошибка, которая вызвана, видимо, повреждением файлов пакета. К примеру, при попытке обновления я получал ошибку:
При этом сам модуль установлен как следует из самой первой строки.
Проблема может решиться удалением всех файлов пакета (с помощью rm) и затем повторной установки.
К примеру в рассматриваемом случае, удаление:
После этого проблема с модулем исчезла.
Заключение
Пожалуй, это далеко не полный «справочник ошибок Python», но если вы можете сориентироваться, какого рода ошибка у вас возникла:
- отсутствует модуль
- модуль неправильной версии
- модуль повреждён
- внешняя причина — программа не получила ожидаемые данные
Так вот, если вы хотя бы примерно поняли главную причину, то вам будет проще понять, в каком направлении двигаться для её решения.
Python. Урок 16. Установка пакетов в Python
В процессе разработки программного обеспечения на Python часто возникает необходимость воспользоваться пакетом, который в данный момент отсутствует на вашем компьютере. О том, откуда взять нужный вам пакет и как его установить, вы узнаете из этого урока.
Где взять отсутствующий пакет?
Необходимость в установке дополнительного пакета возникнет очень быстро, если вы решите поработать над задачей, за рамками базового функционала, который предоставляет Python . Например: работа с web , обработка изображений, криптография и т.п. В этом случае, необходимо узнать, какой пакет содержит функционал, который вам необходим, найти его, скачать, разместить в нужном каталоге и начать использовать. Все эти действия можно сделать вручную, но этот процесс поддается автоматизации. К тому же скачивать пакеты с неизвестных сайтов может быть довольно опасно.
К счастью для нас, в рамках Python, все эти задачи решены. Существует так называемый Python Package Index (PyPI) – это репозиторий, открытый для всех Python разработчиков, в нем вы можете найти пакеты для решения практически любых задач. Там также есть возможность выкладывать свои пакеты. Для скачивания и установки используется специальная утилита, которая называется pip .
Менеджер пакетов в Python – pip
Pip – это консольная утилита (без графического интерфейса). После того, как вы ее скачаете и установите, она пропишется в PATH и будет доступна для использования.
Эту утилиту можно запускать как самостоятельно:
так и через интерпретатор Python :
Ключ -m означает, что мы хотим запустить модуль (в данном случае pip ). Более подробно о том, как использовать pip , вы сможете прочитать ниже.
Установка pip
При развертывании современной версии Python (начиная с P ython 2.7.9 и Python 3.4),
pip устанавливается автоматически. Но если, по какой-то причине, pip не установлен на вашем ПК, то сделать это можно вручную. Существует несколько способов.
Будем считать, что Python у вас уже установлен, теперь необходимо установить pip . Для того, чтобы это сделать, скачайте скрипт get-pip.py
и выполните его.
При этом, вместе с pip будут установлены setuptools и wheels . Setuptools – это набор инструментов для построения пакетов Python . Wheels – это формат дистрибутива для пакета Python . Обсуждение этих составляющих выходит за рамки урока, поэтому мы не будем на них останавливаться.
Способ для Linux
Если вы используете Linux , то для установки pip можно воспользоваться имеющимся в вашем дистрибутиве пакетным менеджером. Ниже будут перечислены команды для ряда Linux систем, запускающие установку pip (будем рассматривать только Python 3, т.к. Python 2 уже морально устарел, а его поддержка и развитие будут прекращены после 2020 года).
Обновление pip
Если вы работаете с Linux , то для обновления pip запустите следующую команду.
Для Windows команда будет следующей:
Использование pip
Далее рассмотрим основные варианты использования pip : установка пакетов, удаление и обновление пакетов.
Установка пакета
Pip позволяет установить самую последнюю версию пакета, конкретную версию или воспользоваться логическим выражением, через которое можно определить, что вам, например, нужна версия не ниже указанной. Также есть поддержка установки пакетов из репозитория. Рассмотрим, как использовать эти варианты.
Установка последней версии пакета
Установка определенной версии
Установка пакета с версией не ниже 3.1
Установка Python пакета из git репозитория
Установка из альтернативного индекса
Установка пакета из локальной директории
Удаление пакета
Для того, чтобы удалить пакет воспользуйтесь командой
Обновление пакетов
Для обновления пакета используйте ключ –upgrade.
Просмотр установленных пакетов
Для вывода списка всех установленных пакетов применяется команда pip list .
Если вы хотите получить более подробную информацию о конкретном пакете, то используйте аргумент show .
Поиск пакета в репозитории
Если вы не знаете точное название пакета, или хотите посмотреть на пакеты, содержащие конкретное слово, то вы можете это сделать, используя аргумент search .
Где ещё можно прочитать про работу с pip?
В сети довольно много информации по работе с данной утилитой.
Python Packaging User Guide – набор различных руководств по работе с пакетами в Python
P.S.
Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.