Вопрос

В начале всех моих исполняемых скриптов Python я помещаю дело линия:

#!/usr/bin/env python

Я запускаю эти скрипты в системе, где env python выдает среду Python 2.2.Мои скрипты быстро выходят из строя, потому что у меня есть ручная проверка на наличие совместимой версии Python:

if sys.version_info < (2, 4):
    raise ImportError("Cannot run with Python version < 2.4")

Я не хочу менять строку shebang в каждом исполняемом файле, если это возможно;однако у меня нет административного доступа к компьютеру, чтобы изменить результат env python и я не хочу навязывать определенную версию, как в:

#!/usr/bin/env python2.4

Я бы хотел избежать этого, потому что система может иметь более новую версию, чем Python 2.4, или может иметь Python 2.5, но не Python 2.4.

Каково это элегантное решение?

[Редактировать:] Я не был достаточно конкретен в постановке вопроса - я бы хотел, чтобы пользователи выполняли скрипты без ручной настройки (напримеризменение пути или символическая ссылка в ~/bin и обеспечение того, чтобы ваш ПУТЬ имел ~/bin перед путем Python 2.2).Может быть, требуется какая-нибудь утилита распространения, чтобы предотвратить ручные настройки?

Это было полезно?

Решение

"env" просто выполняет первое, что находит в ПУТИ env var.Чтобы переключиться на другой python, добавьте каталог для исполняемого файла этого python к пути перед вызовом вашего скрипта.

Другие советы

Довольно хакерское решение - если ваша проверка не удалась, используйте эту функцию (которая, вероятно, могла бы быть значительно улучшена), чтобы определить лучший доступный интерпретатор, определить, является ли он приемлемым, и, если да, перезапустить ваш скрипт с os.system или чем-то подобным, и ваш sys.argv использует новый интерпретатор.

import os
import glob
def best_python():
    plist = []
    for i in os.getenv("PATH").split(":"):
        for j in glob.glob(os.path.join(i, "python2.[0-9]")):
             plist.append(os.path.join(i, j))
    plist.sort()
    plist.reverse()
    if len(plist) == 0: return None
    return plist[0]

Если вы запускаете сценарии, вы можете установить переменную PATH так, чтобы она сначала указывала на каталог приватного бина:

$ mkdir ~/bin
$ ln -s `which python2.4` ~/bin/python
$ export PATH=~/bin:$PATH

Затем, когда вы выполните свой скрипт на python, он будет использовать python 2.4. Вам придется изменить свои сценарии входа в систему, чтобы изменить свой путь.

В качестве альтернативы запустите скрипт на python с явным интерпретатором, который вам нужен:

$ /path/to/python2.4 <your script>

@мораис:Это интересная идея, но я думаю, может быть, мы сможем сделать еще один шаг вперед.Может быть, есть способ использовать Виртуальный сервер Иэна Бикинга Для:

  • Посмотрите, работаем ли мы в приемлемой среде для начала, и если да, то ничего не предпринимайте.
  • Проверьте, существует ли исполняемый файл, зависящий от конкретной версии, на PATH, т. е.проверьте, есть ли python2.x существует for x in reverse(range(4, 10)).Если это так, повторно запустите команду с лучшим интерпретатором.
  • Если лучшего интерпретатора не существует, используйте virtualenv, чтобы попытаться установить более новую версию Python из более старой версии Python и получить все необходимые пакеты.

Я понятия не имею, способен ли virtualenv на это, поэтому в ближайшее время я с ним повозлюсь.:)

Вот решение, если вы (1) абсолютно настроены на использование shebangs и (2) можете использовать Autotools в процессе сборки.

Я только вчера вечером обнаружил, что вы можете использовать макрос autoconf AM_PATH_PYTHON чтобы найти минимальный Python 2 бинарный.Руководство к действию заключается в следующем здесь.

Итак, ваш процесс был бы следующим:

  • Выдать AM_PATH_PYTHON(2.4) в вашем configure.ac
  • Переименуйте все ваши .py скрипты для .py.in (по моему опыту, это не сбивает с толку vi)
  • Назовите все те скрипты Python, с помощью которых вы хотите сгенерировать AC_CONFIG_FILES.
  • Вместо того, чтобы начинать с #!/usr/bin/env python, использовать #!@PYTHON@

Тогда ваш результирующий Скрипты Python всегда будут иметь соответствующий shebang.

Итак, у вас есть это решение, по крайней мере возможное, если не практичное.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top