Проблемы с несколькими версиями Python 2.x в отношении PYTHONPATH - PullRequest
5 голосов
/ 04 марта 2012

В системе установлен Python 2.6.

Теперь я хочу использовать модули, представленные в Python 2.7. Поскольку у меня нет привилегий root, я собрал и установил 2.7 в своем домашнем каталоге ($ HOME / local /)

Я добавил в свой $ HOME / .bashrc следующее:

export PATH=$HOME/local/bin:$PATH
export PYTHONPATH=$HOME/local/lib/python2.7:$PYTHONPATH

Теперь я столкнулся с двумя проблемами, которые я хочу попросить обойти.

1. Вызов Python 2.7

Недавно установленный Python 2.7 не находит модули 2.6 в пути к системной библиотеке (/usr/lib/python2.6/site-packages/).

Должен ли я добавить его в PYTHONPATH вручную? Есть ли более приятное решение?

2. Вызов Python 2.6

Python 2.6 жалуется при запуске:

'import site' failed; use -v for traceback

Я думаю, он пытается загрузить 2,7 модуля (в $ HOME / local / lib / python2.7). Можно ли загрузить только модули 2.6 при запуске Python 2.6?

Спасибо.

Ответы [ 3 ]

4 голосов
/ 04 марта 2012

1) Вызов питона 2.7

Короче: не делай этого. Есть причины, по которым путь называется '/usr/lib/python*2.6*/site-packages/'.

Одна из причин заключается в том, что в этом каталоге обычно хранятся «скомпилированные» файлы Python (.pyc). Python 2.6 и python 2.7 .pyc файлы не совместимы:

$ python2.7 /usr/lib/python2.6/sitecustomize.pyc
RuntimeError: Bad magic number in .pyc file

python пропустит pyc-файлы, которые он не может понять, но вы потеряете хотя бы преимущества предварительно скомпилированных файлов.

Другая причина в том, что все может смешаться:

$ strace -f python2.7 /usr/lib/python2.6/sitecustomize.py
...
stat("/etc/python2.6", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/etc/python2.6", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/etc/python2.6/apport_python_hook", 0x7fffa15601f0) = -1 ENOENT (No such file or directory)
open("/etc/python2.6/apport_python_hook.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/python2.6/apport_python_hookmodule.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/python2.6/apport_python_hook.py", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/python2.6/apport_python_hook.pyc", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/python2.7/apport_python_hook", 0x7fffa15601f0) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/apport_python_hook.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/apport_python_hookmodule.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/apport_python_hook.py", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/apport_python_hook.pyc", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/python2.7/plat-linux2/apport_python_hook", 0x7fffa15601f0) = -1 ENOENT (No such file or directory)
...

Я бы в вашем случае установил модули, необходимые также для python 2.7, в каталог python2.7.

2) Вызов Python 2.6

Возможно, вы захотите взглянуть на часть справочной страницы, где описывается PYTHONHOME:

PYTHONHOME: изменить расположение стандартных библиотек Python. По умолчанию поиск в библиотеках осуществляется в $ {prefix} / lib / python [версия] и $ {exec_prefix} / lib / python [версия], где $ {prefix} и $ {exec_prefix} являются каталогами, зависящими от установки, оба значения по умолчанию в / usr / local

Вы можете хранить определенные файлы / модули python 2.7 в соответствующем каталоге вашей локальной установки. Эти файлы / модули будут выбраны только при запуске конкретной версии Python. В этом случае вы не должны устанавливать PYTHONPATH (или PYTHONHOME).

Примечание: именно так Debian (и, возможно, другие дистрибутивы) управляют различными одновременно установленными версиями python.

[Редактировать: Добавлен раздел 1 после получения комментария от niboshi.]

2 голосов
/ 04 марта 2012

При запуске Python берет переменную окружения PYTHONPATH и помещает ее в переменную sys.path. При попытке импортировать модуль он ищет пути в sys.path

Из-за:

export PYTHONPATH=$HOME/local/lib/python2.7:$PYTHONPATH

Ваши пути в Python 2.7 находятся в начале sys.path, перед путями в Python 2.6 (Вы можете print sys.path проверить). Это означает, что модули из $HOME/local/lib/python2.7 будут иметь приоритет.

Чтобы настроить пути для некоторых из ваших сценариев, либо установите PYTHONPATH для каждого сценария, либо измените sys.path (sys.path.insert(0, '/home/user/local/lib/python2.7') прямо в вашем сценарии перед выполнением любого импорта.

Или скопируйте определенный модуль в ваш проект под другим именем. Например, я скопировал модуль collections из Python 2.7 в мой проект как collections27.py, и в местах, где мне нужно OrderedDict, я делаю from collection27 import OrderedDict

Можно ли загружать только модули 2.6 при вызове Python 2.6?

Да, я думаю. Просто убедитесь, что в пути только модули Python 2.6 - не используйте:

export PYTHONPATH=$HOME/local/lib/python2.7:$PYTHONPATH
0 голосов
/ 04 марта 2012

Могу ли я предложить pythonbrew в качестве более легкой альтернативы.

Как только вы установили pythonbrew:

$ pythonbrew install 2.7.2
$ pythonbrew switch 2.7.2
...