Если у меня есть сценарий Python, для которого требуется хотя бы определенная версия Python, как правильно выполнить корректный сбой при использовании более ранней версии Python для запуска сценария?
Как получить контроль достаточно рано, чтобы выдать сообщение об ошибке и выйти?
Например, у меня есть программа, которая использует оператор ternery (новый в 2.5) и блоки «with» (новый в 2.6). Я написал простую небольшую подпрограмму проверки версии интерпретатора, которая является первой вещью, которую вызовет сценарий ... за исключением того, что она не зашла так далеко. Вместо этого сценарий завершается ошибкой во время компиляции Python, прежде чем мои процедуры будут даже вызваны. Таким образом, пользователь сценария видит некоторые очень неясные трассировки ошибок Synax, которые в значительной степени требуют от эксперта, чтобы сделать вывод, что это просто случай запуска неправильной версии Python.
Я знаю, как проверить версию Python. Проблема в том, что какой-то синтаксис недопустим в старых версиях Python. Рассмотрим эту программу:
import sys
if sys.version_info < (2, 4):
raise "must use python 2.5 or greater"
else:
# syntax error in 2.4, ok in 2.5
x = 1 if True else 2
print x
При запуске под 2.4, я хочу этот результат
$ ~/bin/python2.4 tern.py
must use python 2.5 or greater
а не этот результат
$ ~/bin/python2.4 tern.py
File "tern.py", line 5
x = 1 if True else 2
^
SyntaxError: invalid syntax
(Ченнелинг для коллеги.)
Ответы:
Вы можете проверить, используя
eval
:Кроме того ,
with
это доступно в Python 2.5, просто добавитьfrom __future__ import with_statement
.РЕДАКТИРОВАТЬ: чтобы получить контроль достаточно рано, вы можете разбить его на разные
.py
файлы и проверить совместимость в главном файле перед импортом (например, в__init__.py
пакете):источник
exec
вместоeval
. У меня было это при попытке написать функцию, которая будет печатать в stderr как в py2k, так и в py3k.import
станцию в try / исключением). Обратите внимание, что вам может потребоваться проверить другие вещи, кромеSyntaxError
как (например, встроенные функции или дополнения к стандартной библиотеке)Имейте обертку вокруг своей программы, которая делает следующее.
Вы также можете рассмотреть возможность использования
sys.version()
, если вы планируете встретить людей, которые используют интерпретаторы Python до 2.0, но тогда у вас есть некоторые регулярные выражения, которые нужно сделать.И могут быть более элегантные способы сделать это.
источник
sys.version_info
это не функция.import this
. Прекрасная диверсия.Пытаться
Должен дать вам строку типа «2.3.1». Если это не совсем то, что вам нужно, есть богатый набор данных, доступных через встроенную платформу. То, что вы хотите, должно быть где-то там.
источник
print(platform.python_version())
вместоplatform.python_version()
!Вероятно, лучший способ сделать это сравнение версий - использовать
sys.hexversion
. Это важно, потому что сравнение кортежей версий не даст желаемого результата во всех версиях Python.источник
источник
sys.version_info
это не именованный кортеж. Вам нужно будет использоватьsys.version_info[0]
как основной номер версии, так иsys.version_info[1]
младший.Вы также можете проверить версию Python из самого кода, используя
platform
модуль из стандартной библиотеки.Есть две функции:
platform.python_version()
(возвращает строку).platform.python_version_tuple()
(возвращает кортеж).Код Python
Простой способ проверить версию:
Вы также можете использовать
eval
метод:Запустите файл Python из командной строки:
Вывод Python с CGI через сервер WAMP в Windows 10:
Полезные ресурсы
источник
Наборы стали частью основного языка в Python 2.4, чтобы оставаться обратно совместимыми. Я сделал это тогда, что будет работать и для вас:
источник
try: set except NameError: from sets import Set as set
Хотя вопрос таков: как получить контроль достаточно рано, чтобы выдать сообщение об ошибке и выйти ?
Вопрос, на который я отвечаю: как получить контроль достаточно рано, чтобы выдать сообщение об ошибке перед запуском приложения ?
Я могу ответить на это по-другому, чем другие посты. Кажется, ответы до сих пор пытаются решить ваш вопрос изнутри Python.
Я говорю, сделайте проверку версии перед запуском Python. Я вижу, ваш путь - это Linux или Unix. Однако я могу предложить вам только сценарий Windows. Я представляю, что адаптировать его к синтаксису сценариев Linux не будет слишком сложно.
Вот сценарий DOS с версией 2.7:
Это не запускает какую-либо часть вашего приложения и, следовательно, не вызовет исключение Python. Он не создает временный файл и не добавляет никаких переменных среды ОС. И это не заканчивает ваше приложение исключением из-за различных правил синтаксиса версий. Это три менее возможных точки безопасности доступа.
FOR /F
Линия является ключевой.Для нескольких версий Python проверьте URL: http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=17
И моя версия взлома:
[MS скрипт; Проверка версии Python перед запуском модуля Python] http://pastebin.com/aAuJ91FQ
источник
будет получать ответ, как это
здесь 2.7.6 - версия
источник
Как отмечено выше, синтаксические ошибки возникают во время компиляции, а не во время выполнения. Хотя Python является «интерпретируемым языком», код Python фактически не интерпретируется напрямую; он компилируется в байтовый код, который затем интерпретируется. Существует этап компиляции, который происходит, когда модуль импортируется (если нет уже скомпилированной версии в виде файла .pyc или .pyd), и именно тогда вы получаете ошибку, а не (совершенно точно), когда ваш код работает
Вы можете отложить шаг компиляции и сделать это во время выполнения для одной строки кода, если хотите, используя eval, как отмечено выше, но я лично предпочитаю избегать этого, потому что это заставляет Python выполнять потенциально ненужная компиляция во время выполнения, с одной стороны, и с другой, создает то, что для меня ощущается как беспорядок в коде. (Если вы хотите, вы можете сгенерировать код, который генерирует код, который генерирует код - и у вас есть совершенно невероятное время, чтобы изменить и отладить его через 6 месяцев.) Поэтому вместо этого я бы порекомендовал нечто подобное:
... что я бы сделал, даже если бы у меня была только одна функция, использующая новый синтаксис, и она была очень короткой. (На самом деле я бы принял все разумные меры, чтобы минимизировать количество и размер таких функций. Я мог бы даже написать такую функцию, как ifTrueAElseB (cond, a, b) с этой единственной строкой синтаксиса.)
Еще одна вещь, на которую стоит обратить внимание (на которую я немного удивлен, пока никто не указал), это то, что хотя более ранние версии Python не поддерживали такой код, как
..это действительно поддерживает код как
Это был старый способ написания троичных выражений. У меня еще не установлен Python 3, но, насколько мне известно, этот «старый» способ работает до сих пор, так что вы можете сами решить, стоит ли его условно использовать новый синтаксис, если вам нужно поддерживать использование более старых версий Python.
источник
a and b or c
вместоb if a else c
, это не эквивалентно; еслиb
это ложь, то она потерпит неудачу, производя,a
а неb
.Поместите следующее в самый верх вашего файла:
Затем продолжите с нормальным кодом Python:
источник
sys.version_info < (2, 7)
sys.version_info
типа с кортежем?sys.version_info
раньше был кортежем; например(2, 4, 6, 'final', 0)
; только в Python 3 и 2.7 он был изменен на отдельный тип, который, тем не менее, сопоставим с кортежами.Я думаю, что лучший способ - это проверить функциональность, а не версии. В некоторых случаях это тривиально, а в других - нет.
например:
Пока вы достаточно конкретны в использовании блоков try / Кроме того, вы можете охватить большинство ваших баз.
источник
Я только нашел этот вопрос после быстрого поиска, пытаясь решить проблему самостоятельно, и я придумал гибрид, основанный на нескольких предложениях выше.
Мне нравится идея DevPlayer об использовании скрипта-обертки, но недостатком является то, что в итоге вы поддерживаете несколько оберток для разных ОС, поэтому я решил написать обертку на python, но использовать ту же базовую логику «захватить версию, запустив exe» и придумал это.
Я думаю, что это должно работать на 2,5 и далее. Я проверил это на 2.66, 2.7.0 и 3.1.2 на Linux и 2.6.1 на OS X до сих пор.
Да, я знаю, что окончательная линия декодирования / полосы ужасна, но я просто хотела быстро получить номер версии. Я собираюсь уточнить это.
Пока это работает достаточно хорошо для меня, но если кто-то сможет улучшить его (или скажите мне, почему это ужасная идея), это тоже будет круто.
источник
Для автономных сценариев Python работает следующий трюк docstring модуля для принудительного применения версии Python (здесь v2.7.x) (протестировано на * nix).
Это также должно обрабатывать отсутствующий исполняемый файл Python, но зависит от grep. Смотрите здесь для фона.
источник
Вы можете проверить с помощью
sys.hexversion
илиsys.version_info
.sys.hexversion
не очень удобен для человека, потому что это шестнадцатеричное число.sys.version_info
это кортеж, поэтому он более дружелюбен к человеку.Проверьте для Python 3.6 или новее с
sys.hexversion
:Проверьте для Python 3.6 или новее с
sys.version_info
:sys.version_info
более дружественный к человеку, но принимает больше персонажей. Я бы порекомендовалsys.hexversion
, хотя это менее дружелюбно к человеку.Я надеюсь, что это помогло вам!
источник
Я расширяю превосходный ответ Ахана, который печатает полезное сообщение еще до того, как скрипт Python будет скомпилирован.
Если вы хотите убедиться, что скрипт выполняется с Python 3.6 или новее, добавьте эти две строки в начало вашего скрипта Python:
(Примечание. Вторая строка начинается с четырех одинарных кавычек и заканчивается тремя одинарными кавычками. Это может показаться странным, но это не опечатка.)
Преимущество этого решения в том, что подобный код
print(f'Hello, {name}!')
не будет вызывать,SyntaxError
если используется версия Python старше 3.6. Вместо этого вы увидите это полезное сообщение:Конечно, это решение работает только на Unix-подобных оболочках и только тогда, когда скрипт вызывается напрямую (например
./script.py
,:), и с установленными битами разрешений eXecute.источник
Как насчет этого:
источник
Проблема довольно проста. Вы проверили, была ли версия меньше 2,4, не меньше или равна . Так что, если версия Python 2.4, она не меньше 2.4. Что вы должны были иметь:
не
источник