Как проверить, какая версия Python использует мой скрипт?

1186

Как я могу проверить, какая версия интерпретатора Python интерпретирует мой скрипт?

перевозчик
источник
1
Текущий поток о проверке версии Python из программы / скрипта Python. Если вы хотите проверить версию интерпретатора Python, установленного на вашем компьютере, из командной строки, пожалуйста, обратитесь к следующему сообщению - Какую версию Python я установил?
RBT
1
вот забавный способ разделить Python 3 и 2 ...python_version = int(str(range(3))[-2])
Chris_Rands
@RBT: для проверки в одну строку из командной строки, смотрите мой ответ .
СМСИ

Ответы:

1380

Эта информация доступна в строке sys.version в модуле sys :

>>> import sys

Человек читаемый:

>>> print(sys.version)  # parentheses necessary in python 3.       
2.5.2 (r252:60911, Jul 31 2008, 17:28:52) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)]

Для дальнейшей обработки:

>>> sys.version_info
(2, 5, 2, 'final', 0)
# or
>>> sys.hexversion
34014192

Чтобы скрипт работал с минимальными требованиями к версии интерпретатора Python, добавьте его в свой код:

assert sys.version_info >= (2, 5)

Это сравнивает основные и второстепенные версии информации. Добавьте micro (= 0, 1и т. Д.) И даже уровень выпуска (= 'alpha', 'final'и т. Д.) В кортеж, как вам нравится. Тем не менее, обратите внимание, что почти всегда лучше проверять наличие определенной функции и, если нет, обходной путь (или выход из кризиса). Иногда функции уходят в новых версиях, заменяя их другими.

krawyoti
источник
39
это на самом деле синтаксис для печати. не для проверки версии. Я использую это в моих скриптах Python 2 и 3:PY3 = sys.version_info[0] == 3
gcb
5
PY2 = sys.version_info [0] == 2 PY3 = sys.version_info [0] == 3
xiaoweiz
25
Вы также можете получить доступ к некоторым полям в sys.version_infoкачестве свойств, поэтому они PY3 = sys.version_info.major == 3могут быть немного более привлекательными.
krs013
1
Примечание: sys.hexversion сравнивается с 0x020502F0, см. Docs.python.org/2/library/sys.html#sys.hexversion
Эрлих,
1
@gcb ваш фрагмент кода будет ломаться всякий раз, когда появится Python 4. Вы должны сделать if sys.version_info >= (3,). Сравнивать кортежи разного размера - это совершенно питонно, и все будет правильно.
Борис
373

Из командной строки (обратите внимание на заглавную букву 'V'):

python -V

Это задокументировано в «man python».

jcolino
источник
13
прописная буква V - версия, а не строчная
Rogue
96

Мне нравится такие sys.hexversionвещи, как это.

http://docs.python.org/library/sys.html#sys.hexversion

>>> import sys
>>> sys.hexversion
33883376
>>> '%x' % sys.hexversion
'20504f0'
>>> sys.hexversion < 0x02060000
True
brianz
источник
Это отличная версия, которую я не видел, и немного проще в использовании (по крайней мере, для меня), чем обычная версия ...
Уэйн Вернер
6
@sorin: можете ли вы объяснить, как это лучше, чем, например, ответ Сета? Так как вы утверждаете, что это лучшее, мне интересно.
0xC0000022L
3
@ 0xC0000022L Задумывались ли вы, как вы сможете сравнить текст из кортежа? Как «финал» сравнивается с бета, rc или чем-то еще, что может быть там. Вместо этого, если у вас есть числовое значение, вы всегда сможете указать точную версию.
сорин
1
@sorin: хм, это не имеет значения, не так ли? Если сравнивать с , кажется , не влияет на сравнение и не предполагается. Очевидно, что при сравнении «наиболее значимых» частей кортежа нарезка не требуется. Похоже, это то, как к этому относятся, и вот о чем был мой вопрос. Я не говорю, что это решение не имеет смысла, я просто удивляюсь, почему оно лучшее - то, что мне не хватает. (2,6,4)'final'
0xC0000022L
11
Уровень релиза определяется как «альфа», «бета», «кандидат» или «финал», который также сравнивается корректно ...
Фредрик
65

Ваша лучшая ставка, вероятно, примерно такая:

>>> import sys
>>> sys.version_info
(2, 6, 4, 'final', 0)
>>> if not sys.version_info[:2] == (2, 6):
...    print "Error, I need python 2.6"
... else:
...    from my_module import twoPointSixCode
>>> 

Кроме того, вы всегда можете заключить импорт в простую попытку, которая должна отлавливать синтаксические ошибки. И, к слову @ Heikki, этот код будет совместим с гораздо более старыми версиями python:

>>> try:
...     from my_module import twoPointSixCode
... except Exception: 
...     print "can't import, probably because your python is too old!"
>>>
Сет
источник
3
Почему простое исключение, а не ошибка ImportError? : P
смертельно
4
@deadly - ImportError не будет перехватывать SyntaxErrors, которые будут выброшены, если вы попытаетесь использовать новый синтаксис в старом питоне, например, попытаться использовать условный ярлык в pre-2.5.
Сет
except Exceptionслишком широк. Не лучше ли использовать конкретные исключения, которые вы ожидаете?
Парадокс Ферми
1
@Fermiparadox - Широкий выбор делает предположения низкими. except Exception:Линия сама по себе уже предполагает современную (2.x +) питон. Может быть, какой-нибудь будущий питон переставит имена исключений каким-то образом, несовместимым с прошлым? (? Наверное , нет, но кто знает , что питон будет выглядеть в 20 лет , когда все мы имеем Oculus имплантаты разлом глазного яблока код длится долгое время.)
Seth
65

Используйте platformspython_version из stdlib:

>>> from platform import python_version
>>> print(python_version())
2.7.8
Билл
источник
5
Для функции печати лучше было бы в скобках подумать о совместимости. Если кто-то использует образец в версии 3, синтаксическая ошибка будет там в ожидании.
Алекс Чан
47

Положите что-то вроде:

#!/usr/bin/env/python
import sys
if sys.version_info<(2,6,0):
  sys.stderr.write("You need python 2.6 or later to run this script\n")
  exit(1)

в верхней части вашего сценария.

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

rjmunro
источник
6
Это неверно (или, по крайней мере, неполно), потому что старые интерпретаторы будут препятствовать использованию новых языковых конструкций, таких как x if Pred() else y. Они умрут во время фазы «лексинга», и у них никогда не будет шанса на самом деле казнить exit(1) . Ответ Сета верен в инкапсуляции новых возможностей языка в других файлах.
Марк Рушаков
2
@MarkRushakoff: ваш комментарий сбивает с толку. Какой аспект этого ответа не так? Отсутствующая elseветка или что за <используется version_info? AFAIK Python дополняет пропущенные значения в кортежах, и все это должно быть допустимо до 2.6, нет? Так что ответ Сета использует нарезку (избыточно), а этот - нет, и это делает ваш комментарий еще более запутанным.
0xC0000022L
5
Я думаю, что @MarkRushakoff говорит, что если у вас есть это в верхней части файла, и новая языковая функция в другом месте того же файла, старая версия python умрет при загрузке файла, прежде чем он запустит какой-либо из них, поэтому ошибка не будет отображаться. По сути, вы должны поместить вышеупомянутую (или другую проверку) в начало файла, а затем импортировать код, для которого требуется новая версия python, из отдельных файлов.
rjmunro
1
Да, что сказал @rjmunro :)
Марк Рушаков
24

Вот короткая версия командной строки, которая выходит сразу (удобно для сценариев и автоматического выполнения):

python -c "print(__import__('sys').version)"

Или только мажор, минор и микро

python -c "print(__import__('sys').version_info[:1])" # (2,)
python -c "print(__import__('sys').version_info[:2])" # (2, 7)
python -c "print(__import__('sys').version_info[:3])" # (2, 7, 6)
Wolph
источник
1
@vigilancer вы правы, на момент написания статьи это еще не было актуально, но я обновил его для Python 3 :)
Wolph
Хорошо, это решает мою проблему, когда я получал номер версии, захватив выходные данные python2 --versionи python3 --versionиз PHP. В то время как я получал бы последний без проблем через него passthru(), первый печатал только на экран, но никогда не
Tox
1
@tox Вы можете сказать, print() чтобы записать в файл, если это более удобно.
Вольф
В моем случае это было бы больше того же, что я уже перенаправил passthru()вывод в файл. Ваше решение делает именно то, что мне нужно. :)
Токс
14

С sixмодулем вы можете сделать это:

import six

if six.PY2:
  # this is python2.x
else:
  # six.PY3
  # this is python3.x
Dzhuang
источник
8
import sys
sys.version.split(' ')[0]

sys.version дает вам то, что вы хотите, просто выберите первый номер :)

fengshaun
источник
4

Как сказал Сет, основной сценарий может проверить sys.version_info (но учтите, что он появился только до 2.0, поэтому, если вы хотите поддерживать более старые версии, вам нужно проверить другое свойство версии модуля sys).

Но вам все равно нужно позаботиться о том, чтобы в файле не использовались какие-либо функции языка Python, которые недоступны в более старых версиях Python. Например, это разрешено в Python 2.5 и более поздних версиях:

try:
    pass
except:
    pass
finally:
    pass

но не будет работать в более старых версиях Python, потому что вы можете иметь только, кроме ИЛИ, наконец, сопоставить попытку. Поэтому для совместимости со старыми версиями Python вам нужно написать:

try:
    try:
        pass
    except:
        pass
finally:
    pass
Хейкки Тойвонен
источник
4

Самый простой способ

Просто введите Python в свой терминал, и вы можете увидеть версию, как показано ниже

desktop:~$ python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
cjahangir
источник
24
«Самый простой способ» ... сделать что-то отличное от того, о чем просили.
Люк
2

Несколько ответов уже предлагают, как запросить текущую версию Python. Чтобы программно проверить требования к версии, я бы использовал один из следующих двух методов:

# Method 1: (see krawyoti's answer)
import sys
assert(sys.version_info >= (2,6))

# Method 2: 
import platform
from distutils.version import StrictVersion 
assert(StrictVersion(platform.python_version()) >= "2.6")
normanius
источник
2

Просто для удовольствия, вот способ сделать это на CPython 1.0-3.7b2, Pypy, Jython и Micropython. Это скорее любопытство, чем способ сделать это в современном коде. Я написал его как часть http://stromberg.dnsalias.org/~strombrg/pythons/ , которая является скриптом для тестирования фрагмента кода на многих версиях Python одновременно, так что вы можете легко понять, что такое Python какие функции совместимы с какими версиями python:

via_platform = 0
check_sys = 0
via_sys_version_info = 0
via_sys_version = 0
test_sys = 0
try:
    import platform
except (ImportError, NameError):
    # We have no platform module - try to get the info via the sys module
    check_sys = 1

if not check_sys:
    if hasattr(platform, "python_version"):
        via_platform = 1
    else:
        check_sys = 1

if check_sys:
    try:
        import sys
        test_sys = 1
    except (ImportError, NameError):
        # just let via_sys_version_info and via_sys_version remain False - we have no sys module
        pass

if test_sys:
    if hasattr(sys, "version_info"):
        via_sys_version_info = 1
    elif hasattr(sys, "version"):
        via_sys_version = 1
    else:
        # just let via_sys remain False
        pass

if via_platform:
    # This gives pretty good info, but is not available in older interpreters.  Also, micropython has a
    # platform module that does not really contain anything.
    print(platform.python_version())
elif via_sys_version_info:
    # This is compatible with some older interpreters, but does not give quite as much info.
    print("%s.%s.%s" % sys.version_info[:3])
elif via_sys_version:
    import string
    # This is compatible with some older interpreters, but does not give quite as much info.
    verbose_version = sys.version
    version_list = string.split(verbose_version)
    print(version_list[0])
else:
    print("unknown")
dstromberg
источник
2

Если вы хотите обнаружить pre-Python 3 и не хотите ничего импортировать ...

... вы можете (ab) использовать изменения области видимости списка и сделать это в одном выражении :

is_python_3_or_above = (lambda x: [x for x in [False]] and None or x)(True)
user541686
источник
2
from sys import version_info, api_version, version, hexversion

print(f"sys.version: {version}")
print(f"sys.api_version: {api_version}")
print(f"sys.version_info: {version_info}")
print(f"sys.hexversion: {hexversion}")

вывод

sys.version: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]
sys.api_version: 1013
sys.version_info: sys.version_info(major=3, minor=6, micro=5, releaselevel='final', serial=0)
sys.hexversion: 50726384
Отци
источник
Для Python 2.7 мы должны использовать print("sys.version: {}".format(version)).
Марко
@ Марко, верно. Форматирование строки выполняется для v 3+ с аргументами ключевых слов. можно сделать как print ('[{}, {}, {}]'. format (1,2,3)) для python 2.7 ref: stackoverflow.com/questions/517355/string-formatting-in-python
oetzi
1

Проверьте версию Python: python -Vили python --versionилиapt-cache policy python

Вы также можете запустить, whereis pythonчтобы увидеть, сколько версий установлено.

Шусен Йи
источник
4
Тот же ответ уже был опубликован. и, вопрос не в том, «Как проверить, какую версию Python я установил?» но "Как мне проверить версию в моем скрипте".
Стэнли Коу
1

sys.version_infoне возвращает tuple3,7. Скорее, он возвращает специальный класс, поэтому все примеры, использующие кортежи, не работают, по крайней мере, для меня. Вот вывод из консоли Python:

>>> import sys
>>> type(sys.version_info)
<class 'sys.version_info'>

Я обнаружил, что с помощью комбинации sys.version_info.majorи, sys.version_info.minorкажется, достаточно. Например,...

import sys
if sys.version_info.major > 3:
    print('Upgrade to Python 3')
    exit(1)

проверяет, работает ли Python 3. Вы даже можете проверить более конкретные версии с ...

import sys
ver = sys.version_info
if ver.major > 2:
    if ver.major == 3 and ver.minor <= 4:
        print('Upgrade to Python 3.5')
        exit(1)

можете проверить, если вы используете хотя бы Python 3.5.

Паркер Э.
источник
1
Это что-то вроде подкласса, namedtupleи сравнение с кортежем определенно работает. Чтобы получить полное равенство, вам нужен тип из пяти элементов: главный, младший, микро, уровень выпуска (строка) и серийный номер.
Михаил Едошин
1

Чтобы проверить версию Python для команд в Windows, выполните следующие команды в командной строке и проверьте вывод

c:\>python -V
Python 2.7.16

c:\>py -2 -V
Python 2.7.16

c:\>py -3 -V
Python 3.7.3

Также, чтобы увидеть конфигурацию папки для каждой версии Python, выполните следующие команды:

For Python 2,'py -2 -m site'
For Python 3,'py -3 -m site'
Аамир М Меман
источник
-1

Если вы работаете над Linux, просто введите python вывод команды так:

Python 2.4.3 (# 1, 11 июня 2009, 14:09:37)

[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] на linux2

Введите «помощь», «авторское право», «кредиты» или «лицензия» для получения дополнительной информации.

пкм
источник
6
Я хочу, чтобы мой скрипт на python мог получить версию python, которая его интерпретирует. Правильный ответ принят.
перевозчик
Не помогает получить Pythonверсию в скрипте, также похожий ответ, уже опубликованный ранее: stackoverflow.com/a/35294211/950762
Акиф
-1

Еще более простой способ:

В Spyder запустите новую «Консоль IPython», затем запустите любой из существующих сценариев.

Теперь версию можно увидеть в первом выводе, напечатанном в окне консоли:

«Python 3.7.3 (по умолчанию, 24 апреля 2019, 15:29:51) ...»

введите описание изображения здесь

С. Ессен
источник
-1

Чтобы проверить из командной строки, в одной единственной команде, но включить главную, вспомогательную, микро-версию, уровень выпуска и серийный номер , затем вызовите тот же интерпретатор Python (т. Е. Тот же путь), который вы используете для своего сценария:

> path/to/your/python -c "import sys; print('{}.{}.{}-{}-{}'.format(*sys.version_info))"

3.7.6-final-0

Примечание: .format()вместо f-строк или '.'.join()позволяет вам использовать произвольное форматирование и разделительные символы, например, чтобы сделать это строкой из одного слова с возможностью распознавания. Я поместил это в служебный скрипт bash, который сообщает обо всех важных версиях: python, numpy, pandas, sklearn, MacOS, xcode, clang, brew, conda, anaconda, gcc / g ++ и т. Д. Полезно для регистрации, репликации, устранения неполадок, отчетов об ошибках и т. Д. ,

SMCI
источник
Этот ответ будет уместен для другого вопроса, такого как тот, который указан в комментариях к вопросу. Это не подходит для определения того, какая версия Python выполняет сценарий из этого сценария, поскольку нет гарантии, что pythonкоманда вызовет этот конкретный интерпретатор Python.
user2357112 поддерживает Monica
@ user2357112supportsMonica: этот ответ совершенно соответствует предложенному вопросу. Вопрос, как заявлено, нигде не говорит «изнутри сценария». Если бы это было так, это было бы иначе. Очевидно, что этот ответ подразумевает «вызов того же интерпретатора Python, т.е. того же пути, который вы использовали для своего сценария». Но если вы настаиваете, что я должен отредактировать это в ответ, я буду.
smci