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

Как добавить путь к sys.path в Python?

Описание проблемы:

Используя pip, я обновил до последней версии requests (версия 2.7.0, с pip show requests с указанием местоположения /usr/local/lib/python2.7/dist-packages). Когда я import requests и печатаю requests.__version__ в интерактивной командной строке, я вижу версию 2.2.1. Оказывается, Python использует предварительно установленную версию запросов Ubuntu (requests.__file__ is /usr/lib/python2.7/dist-packages/requests/__init__.pyc - not /user/local/lib/...).

Из моего исследования этот факт вызван изменениями Ubuntu в пути поиска Python (я запускаю Ubuntu 14.04), добавив путь к пакету Ubuntu Python (для моей машины это происходит в usr/local/lib/python2.7/dist-packages/easy-install.pth). В моем случае это вызывает версию запросов apt-get, которая предварительно упакована с Ubuntu, которая будет использоваться, а не версия pip, которую я хочу использовать.

Что я ищу:

Я хочу глобально добавить путь к каталогу установки пути к пути поиска Python (sys.path) до пути к каталогу установки Ubuntu Python. Поскольку запросы (и многие другие пакеты) используются во многих сценариях Python, я не хочу вручную изменять путь поиска для каждого отдельного файла на моей машине.

Неудовлетворительное Решение 1: Использование virtualenv

Использование virtualenv приведет к ненужной замене моей машины, поскольку мне придется переустанавливать каждый пакет, который существует глобально. Я хочу только обновить пакеты Ubuntu до пакетов пакетов.

Неудовлетворительное Решение 2. Изменение easy-install.pth

Так как easy-install.pth перезаписывается каждый раз, когда используется easy-install, мои изменения на easy-install.pth будут удалены, если будет установлен новый пакет. Эта проблема затрудняет сохранение пакетов на моей машине.

Неудовлетворительное (но лучшее, что у меня есть) Решение 3. Добавление отдельного файла .pth

В том же каталоге, что и easy-install.pth, я добавил zzz.pth с содержимым:

import sys; sys.__plen = len(sys.path)
/usr/lib/python2.7/dist-packages/test_dir
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)

Этот файл читается site.py при запуске Python. Поскольку имя файла появляется после easy-install.pth alphanumerically, оно потребляется site.py после этого. Взятые вместе, первая и последняя строки файла добавляют путь к sys.path (эти строки были взяты из easy-install.pth).

Мне не нравится, как это решение зависит от буквенно-цифрового упорядочения имени файла, чтобы правильно разместить новый путь.

PYTHONPATH появляются после путей Ubuntu

Другой ответ о переполнении стека не работал у меня. Мои пути PYTHONPATH появляются после путей в easy-install.pth, которые используют тот же самый код, который я упоминаю в "Неудовлетворительном решении 3" для добавления его путей.

Заранее благодарю вас!

4b9b3361

Ответ 1

Это не рекомендуется, так как он жестко кодирует путь и затрудняет запуск сценария в другом месте, но вы можете сделать это

>>> import sys
>>> sys.path.insert(0,'/home/anand/')
>>> print(sys.path)
['/home/anand/', '', '/usr/local/lib/python2.7/dist-packages/_pdbpp_path_hack', '/usr/local/lib/python2.7/dist-packages/goose-0.0.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/jieba-0.33-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/cssselect-0.9.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/nanoservice-0.1.5-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/nanomsg-1.0a2-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/msgpack_python-0.4.2-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/DecisionTree-2.2.5-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/nudepy-0.2-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/wsgilog-0.3-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/distribute-0.7.3-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/PIL-1.1.7-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/munkres-1.0.7-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/parsedatetime-1.4-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/argparse-1.3.0-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/tusker-0.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/SQLAlchemy-1.0.3-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/numpy-1.9.2-py2.7-linux-x86_64.egg', '/usr/local/lib/python2.7/dist-packages/turkic-0.2.5-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/scikits.bootstrap-0.3.2-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/pyvision-0.1-py2.7-linux-x86_64.egg', '/home/anand/playspace/languages/python_pkgs/ets', '/usr/local/lib/python2.7/dist-packages/Scrapy-1.1.0dev1-py2.7.egg', '/usr/lib/python2.7/dist-packages', '/home/anand/playspace', '/home/anand/workspace/pyvision/src', '/home/anand/playspace/yapf', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/Orange/orng', '/usr/local/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2']
>>>

После этого ваш импорт будет смотреть на предварительно подготовленный путь, прежде чем искать в другом месте.

Ответ 2

Вам не нужно путаться с путём pip, python фактически обрабатывает его автоматически в моем опыте. Кажется, у вас установлено два питона. Если вы наберете:

which pip
which python

какие пути вы видите? Если они не находятся в одной папке /bin, тогда это ваша проблема. Я предполагаю, что используемый вами python (возможно, исходный системный) не содержит его собственный пипс. Вероятно, вам просто нужно убедиться, что путь для python, который вы хотите запустить, должен появиться перед /usr/bin в вашем .bashrc или .zshrc

Если это правильно, вы должны увидеть, что:

which easy_install

использует тот же путь, что и используемая вами установка python, возможно, под /usr/local/bin. Затем просто запустите:

easy_install pip

И начните установку правильных пакетов для используемого питона.

Ответ 3

Использование virtualenv приведет к ненужной замене моей машины, поскольку мне придется переустанавливать каждый пакет, который существует глобально. Я хочу только обновить пакеты Ubuntu до пакетов пакетов.

Нет, вы можете использовать --system-site-packages.

Edit

# make your new virtualenv
[email protected]:~$ mkvirtualenv --system-site-packages max
(max)[email protected]:~$ python
>>> pprint(sys.path)
['',
 '/home/user/.virtualenvs/max/lib64/python27.zip',
 '/home/user/.virtualenvs/max/lib64/python2.7',
 '/home/user/.virtualenvs/max/lib64/python2.7/plat-linux2',
 '/home/user/.virtualenvs/max/lib64/python2.7/lib-tk',
 '/home/user/.virtualenvs/max/lib64/python2.7/lib-old',
 '/home/user/.virtualenvs/max/lib64/python2.7/lib-dynload',
 '/usr/lib64/python2.7',
 '/usr/lib/python2.7',
 '/usr/lib64/python2.7/lib-tk',
 '/home/user/.virtualenvs/max/lib/python2.7/site-packages',
 '/usr/lib64/python2.7/site-packages/google_api_python_client-1.2-py2.7.egg',
 '/usr/lib64/python2.7/site-packages',
 '/usr/lib64/python2.7/site-packages/PIL',
 '/usr/lib64/python2.7/site-packages/gtk-2.0',
 '/usr/lib64/python2.7/site-packages/IPython/extensions']

Как вы видите, путь к этому virtualenv включает в себя системный путь. Чтобы проверить, работает ли он, я установил пакет по всей системе после создания virtualenv.

[email protected]:~: pip install igraph
Collecting igraph
  Downloading igraph-0.1.8-py2.py3-none-any.whl (119kB)
    100% |████████████████████████████████| 122kB 1.7MB/s
Collecting ipython (from igraph)
  Downloading ipython-3.2.1-py2-none-any.whl (3.4MB)
    100% |████████████████████████████████| 3.4MB 203kB/s 
Installing collected packages: ipython, igraph
Successfully installed igraph-0.1.8 ipython-3.2.1
[email protected]:~: python -c 'print __import__("igraph")'
<module 'igraph' from '/usr/lib64/python2.7/site-packages/igraph/__init__.pyc'>

(max)[email protected]:max$ python -c 'print __import__("igraph")'
<module 'igraph' from '/usr/lib64/python2.7/site-packages/igraph/__init__.pyc'>

Очевидно, что то, что установлено внутри virtualenv, имеет приоритет над общесистемными библиотеками.

Я верю, что отвечаю на ваши потребности.

Ответ 4

Ответ на прямой вопрос

Вы можете создать каталог под sitecustomize в каталоге site-packages. Мы превратим это в модуль sitecustomize, как описано здесь (Python 2 здесь). В частности:

предпринимается попытка импортировать модуль с именем sitecustomize, который может выполнять произвольные настройки для конкретного сайта. Обычно это создается системным администратором в вашем каталоге сайтов-пакетов.

В каталоге sitecustomize создайте файл с именем __init__.py и добавьте манипуляции, которые вы хотите выполнить там. Очень простой пример:

import sys
sys.path = ['/your/path/to/pip/install'] + sys.path

В вашем случае, я думаю, your/path... будет /usr/local/lib/python2.7/dist-packages. Возможно, вы захотите сделать что-то более сложное, но это грубо добавляет к sys.path и запускается всякий раз, когда запускается python (например, запуск интерпретатора в командной строке или запуск python script из файла).

Caveat

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

Мысли о основной проблеме

Я думаю, что @fivetentaylor answer находится на правильном пути здесь - кажется, вы используете pip из одной установки с python исполняемым для другого. Маскирование этого путем путаницы с дорогой может очень запутываться очень быстро. Я определенно гарантирую, что у вас есть отдельный pip для каждой установки python, и вы используете это. Это должно держать отдельные структуры каталогов отдельными установками. В противном случае вы вынуждаете одну установку использовать пакеты из разных установочных каталогов. Нет проблем технически, но сбивать с толку логически.

Ответ 5

Ну, альтернативы, представленные другими, очень приемлемы и даже могут быть лучше. Однако, если вы намерены использовать способ sys.path(), просто используйте его как список и используйте метод insert.

import sys
sys.path.insert(0, "path_to_pip") 
from subprocess import call
call("sudo pip install requests") 

Ответ 6

Я бы сделал это с помощью sitecustomize, как описано в документах site.py. Этот файл импортируется после настройки начального sys.path, и вы можете использовать его для изменения sys.path произвольным образом по мере необходимости.

Я использовал его как системный администратор, чтобы включить пользовательские места выпуска, и он отлично выполняет работу.

https://docs.python.org/2/library/site.html

Ответ 7

В то время как ответ bufh решит вашу проблему, вы, скорее всего, обнаружите, что будет другой пакет, в котором вы не хотите использовать Ubuntu- предоставленная версия. Итак, вот почему вы хотите использовать virtualenvs для управления версиями пакетов (и не пытайтесь переопределить версии системы).

Как вы заметили, порядок sys.path устанавливает порядок обнаружения пакетов python. Это означает, что изменение sys.path влияет на то, как скрипты python находят свой импорт, как написанные вами сценарии, так и предоставленные Ubuntu. Учитывая, что скрипты python используются в программах Ubuntu, можно "разбить" Ubuntu интересными способами, изменив ту версию пакетов python, которые используют программы Ubuntu (что является причиной того, что существуют dist-пакеты).

Чтобы этого избежать, был создан virtualenv, что позволяет эффективно использовать разные пакеты пакетов. Теперь есть куча утилит, которые упрощают использование и управление virtualenvs. Наиболее интересным для вас является pipsi, который создает virtualenv за script и позволяет избежать его активации.

Ответ 8

Из звуков вещей Ubuntu использует файл конфигурации пути пакета как документированный здесь, чтобы настроить любые пакеты, которые он устанавливает.

Глядя на site.py Я вижу, что существует определенный порядок разрешения пути, который вызывает файлы конфигурации, поскольку он решает каталоги пакетов пакетов сайта.

Я думаю, что это дает вам три варианта, которые я вижу:

  • Использовать virtualenv -system-site-пакеты в соответствии с ответом @bufh.
  • Использовать pip user installs для настройки пакетов, которые вам нужны в пути до стандартных пакетов сайта.
  • Используйте sitecustomize, чтобы переписать файл sys.path(например, сначала поместить локальные каталоги).