Jak sprawdzić, która wersja Python uruchamia mój skrypt?


1183

Jak mogę sprawdzić, która wersja interpretera Python interpretuje mój skrypt?


1
Bieżący wątek dotyczy sprawdzania wersji języka Python z programu / skryptu języka Python. Jeśli chcesz sprawdzić wersję interpretera Pythona zainstalowanego na twoim komputerze z wiersza poleceń, zapoznaj się z następującym postem - Którą wersję Pythona zainstalowałem?
RBT,

1
tutaj jest fajny sposób na oddzielenie python 3 i 2 ...python_version = int(str(range(3))[-2])
Chris_Rands

@RBT: dla kontroli jednego wiersza z wiersza poleceń, zobacz moją odpowiedź .
smci

Odpowiedzi:


1377

Ta informacja jest dostępna w ciągu sys.version w module sys :

>>> import sys

Czytelny dla człowieka:

>>> 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)]

Do dalszego przetwarzania:

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

Aby mieć pewność, że skrypt działa przy minimalnej wymaganej wersji interpretera Pythona, dodaj to do swojego kodu:

assert sys.version_info >= (2, 5)

Porównuje główne i drobne informacje o wersji. Dodaj mikro (= 0, 1itp), a nawet releaselevel (= 'alpha', 'final'itp) na krotki jak chcesz. Zauważ jednak, że prawie zawsze lepiej jest „uchylić się”, aby sprawdzić, czy jest tam jakaś funkcja, a jeśli nie, obejście (lub ratowanie). Czasami funkcje znikają w nowszych wersjach, zastępowane przez inne.


39
w rzeczywistości jest to składnia drukowania. nie do sprawdzania wersji. używam tego w moich skryptach Python 2 i 3:PY3 = sys.version_info[0] == 3
gcb

5
PY2 = sys.version_info [0] == 2 PY3 = sys.version_info [0] == 3
xiaoweiz

25
Możesz również uzyskać dostęp do niektórych pól sys.version_infojako właściwości, więc PY3 = sys.version_info.major == 3może być trochę bardziej atrakcyjna.
krs013,

1
Uwaga: sys.hexversion jest porównywany z 0x020502F0, patrz docs.python.org/2/library/sys.html#sys.hexversion
Ehrlich

1
@ gcb fragment kodu ulegnie awarii za każdym razem, gdy wydarzy się Python 4. Powinieneś to zrobić if sys.version_info >= (3,). Porównywanie krotek o różnych rozmiarach jest całkowicie pytoniczne i zrobi to dobrze.
Boris

374

Z wiersza poleceń (zwróć uwagę na wielką literę „V”):

python -V

Jest to udokumentowane w „man python”.


13
Wielka litera V to wersja, a nie małe litery
Łotr

96

Lubię takie sys.hexversionrzeczy.

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

>>> import sys
>>> sys.hexversion
33883376
>>> '%x' % sys.hexversion
'20504f0'
>>> sys.hexversion < 0x02060000
True

To fajna funkcja wersji, której nie widziałem, i nieco łatwiejsza w użyciu (przynajmniej dla mnie) niż zwykła wersja ...
Wayne Werner

6
@sorin: czy możesz wyjaśnić, jak to jest lepsze niż na przykład odpowiedź Setha? Skoro twierdzisz, że to jest najlepsze, zastanawiam się.
0xC0000022L

3
@ 0xC0000022L Czy zastanawiałeś się kiedyś, jak możesz porównać tekst z krotki? Jak „ostateczny” wypada w porównaniu z wersją beta, rc lub czymkolwiek innym. Zamiast tego, jeśli masz wartość liczbową, zawsze będziesz w stanie określić dokładną wersję.
sorin

1
@sorin: uhm, to nie ma znaczenia, prawda? Jeśli porównam z , wydaje się, (2,6,4)że 'final'nie ma to wpływu na porównanie i nie powinno tak być. Najwyraźniej nie trzeba kroić, gdy porównuję „najbardziej znaczące” części krotki. Wydaje się, że tak to jest traktowane i na tym właśnie polegało moje pytanie. Nie twierdzę, że to rozwiązanie nie ma swoich zalet, po prostu zastanawiam się, dlaczego jest najlepsze - czyli tego, czego mi brakuje.
0xC0000022L

11
Poziom wydania jest zdefiniowany jako jeden z „alfa”, „beta”, „kandydat” lub „ostateczny”, który również może być poprawnie porównywany ...
Fredrik

65

Twój najlepszy zakład to prawdopodobnie coś takiego:

>>> 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
>>> 

Ponadto zawsze możesz zawinąć importowane elementy w prostą próbę, która powinna wyłapać błędy składniowe. I, do rzeczy @ Heikki, ten kod będzie kompatybilny ze znacznie starszymi wersjami Pythona:

>>> try:
...     from my_module import twoPointSixCode
... except Exception: 
...     print "can't import, probably because your python is too old!"
>>>

3
Dlaczego zwykły wyjątek, a nie importError? : P
śmiertelnie

4
@deadly - ImportError nie wyłapuje błędów składni, które zostaną wyrzucone, jeśli spróbujesz użyć nowej składni w starym pythonie, na przykład próbując użyć skrótu warunkowego w wersjach wcześniejszych niż 2.5.
Seth

except Exceptionjest zbyt szeroki. Czy nie byłoby lepiej zastosować określone wyjątki, których się spodziewasz?
Paradoks Fermiego

1
@Fermiparadox - Bycie szerokim utrzymuje założenia na niskim poziomie. except Exception:Linia sama już zakłada nowoczesną (2.x +) python. Może jakiś przyszły python zmieni kolejność nazw wyjątków w sposób niezgodny z poprzednimi wersjami? (Prawdopodobnie nie, ale kto wie, jak będzie wyglądał pyton za 20 lat, kiedy wszyscy będziemy mieli implanty oczne oczodołu? Kod trwa długo.)
Seth

65

Stosowanie platform„spython_version od stdlib:

>>> from platform import python_version
>>> print(python_version())
2.7.8

5
W przypadku funkcji drukowania lepiej byłoby w nawiasach, jeśli chodzi o zgodność. Jeśli ktoś użyje próbki w wersji 3, czeka na nią błąd składniowy.
Alex Chiang

47

Umieść coś takiego:

#!/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)

u góry skryptu.

Zauważ, że w zależności od tego, co jeszcze jest w twoim skrypcie, starsze wersje Pythona niż cel mogą nie być w stanie nawet załadować skryptu, więc nie dostaną się wystarczająco daleko, aby zgłosić ten błąd. Aby obejść ten problem, możesz uruchomić powyższy skrypt w skrypcie, który importuje skrypt z bardziej nowoczesnym kodem.


6
Jest to niepoprawne (a przynajmniej niekompletne), ponieważ starzy tłumacze będą obrzucać się nowszymi konstrukcjami językowymi, takimi jak x if Pred() else y. Zginą podczas fazy leksykalnej i nigdy nie będą mieli szansy na wykonanie exit(1) . Odpowiedź Setha jest poprawna w przypadku enkapsulacji nowych funkcji językowych w innych plikach.
Mark Rushakoff,

2
@MarkRushakoff: twój komentarz jest mylący. Który aspekt tej odpowiedzi jest zły? Brakująca elsegałąź lub do której <jest używana version_info? Python AFAIK uzupełnia brakujące wartości w krotkach, a wszystko to powinno być ważne przed 2.6, nie? Tak więc odpowiedź Setha wykorzystuje krojenie (zbędne), podczas gdy ta nie, a to sprawia, że ​​twój komentarz jest jeszcze bardziej mylący.
0xC0000022L

5
Myślę, że @ MarkRushakoff mówi, że jeśli masz to na górze pliku, a nowa funkcja języka w innym miejscu tego samego pliku, stara wersja Pythona umrze podczas ładowania pliku, zanim uruchomi którykolwiek z nich, więc błąd nie będzie wyświetlany. Zasadniczo musisz umieścić powyższe (lub inne sprawdzenie) na górze pliku, a następnie zaimportować kod, który wymaga nowej wersji Pythona z oddzielnych plików.
rjmunro

1
Tak, co powiedział @rjmunro :)
Mark Rushakoff

25

Oto krótka wersja wiersza poleceń, która natychmiast się kończy (przydatna w przypadku skryptów i automatycznego wykonywania):

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

Lub tylko główne, drobne i mikro:

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)

1
@vigilancer masz rację, w chwili pisania tego jeszcze nie było to tak istotne, ale zaktualizowałem go teraz do Python 3 :)
Wolph

Ładne, to rozwiązuje mój problem gdzie byłem coraz numer wersji poprzez przechwytywanie wyjścia python2 --versioni python3 --versionod PHP. Podczas gdy ja dostawałbym ten drugi bez problemów passthru(), pierwszy drukowałby tylko na ekranie, ale nigdy nie został przechwycony, nawet po przekierowaniu do pliku ...
Tox

1
@tox Możesz powiedzieć, print() aby zapisać do pliku, jeśli jest to wygodniejsze.
Wolph

W moim przypadku byłoby to mniej więcej takie samo, jak już przekierowuję dane passthru()wyjściowe do pliku. Twoje rozwiązanie spełnia dokładnie to, czego potrzebuję. :)
Tox

14

Za pomocą sixmodułu możesz to zrobić poprzez:

import six

if six.PY2:
  # this is python2.x
else:
  # six.PY3
  # this is python3.x

8
import sys
sys.version.split(' ')[0]

sys.version daje ci to, czego chcesz, wystarczy wybrać pierwszy numer :)


5

Najprostszy sposób

Po prostu wpisz python w swoim terminalu, a zobaczysz wersję następującą

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.
>>> 

23
„Najprostszy sposób” ... zrobić coś innego niż to, o co został poproszony.
Luc

4

Jak powiedział Seth, skrypt główny mógłby sprawdzić sys.version_info(ale zauważ, że pojawił się dopiero w wersji 2.0, więc jeśli chcesz obsługiwać starsze wersje, musisz sprawdzić właściwość innej wersji modułu sys).

Ale nadal musisz uważać, aby w pliku nie używać żadnych funkcji języka Python, które nie są dostępne w starszych wersjach języka Python. Na przykład jest to dozwolone w Pythonie 2.5 i nowszych:

try:
    pass
except:
    pass
finally:
    pass

ale nie będzie działać w starszych wersjach Pythona, ponieważ możesz mieć tylko OR w końcu dopasować próbę. Aby zachować zgodność ze starszymi wersjami języka Python, musisz napisać:

try:
    try:
        pass
    except:
        pass
finally:
    pass

2

Kilka odpowiedzi już sugeruje, jak wykonać zapytanie do bieżącej wersji Pythona. Aby programowo sprawdzić wymagania dotyczące wersji, skorzystałbym z jednej z dwóch poniższych metod:

# 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")

2

Dla zabawy poniżej opisano sposób na CPython 1.0-3.7b2, Pypy, Jython i Micropython. Jest to bardziej ciekawość niż sposób robienia tego we współczesnym kodzie. Napisałem go jako część http://stromberg.dnsalias.org/~strombrg/pythons/ , który jest skryptem do testowania fragmentu kodu na wielu wersjach Pythona jednocześnie, dzięki czemu można łatwo sprawdzić, który python funkcje są kompatybilne z wersjami Pythona:

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")

2

Sprawdź wersję Python: python -Vlub python --versionlubapt-cache policy python

możesz także uruchomić, whereis pythonaby zobaczyć, ile zainstalowanych wersji.


3
Ta sama odpowiedź została już opublikowana. i pytanie nie brzmi „Jak sprawdzić, którą wersję Pythona zainstalowałem?” ale „Jak sprawdzić wersję w moim skrypcie”.
Stanley Kou,

2

Jeśli chcesz wykryć wersję wcześniejszą niż Python 3 i nie chcesz niczego importować ...

... możesz (ab) użyć zakresu określania zakresu listy i zrobić to w jednym wyrażeniu :

is_python_3_or_above = (lambda x: [x for x in [False]] and None or x)(True)

2

Aby zweryfikować wersję Pythona dla poleceń w systemie Windows, uruchom następujące polecenia w wierszu polecenia i sprawdź dane wyjściowe

c:\>python -V
Python 2.7.16

c:\>py -2 -V
Python 2.7.16

c:\>py -3 -V
Python 3.7.3

Ponadto, aby zobaczyć konfigurację folderu dla każdej wersji Pythona, uruchom następujące polecenia:

For Python 2,'py -2 -m site'
For Python 3,'py -3 -m site'

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}")

wynik

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

W przypadku Python 2.7 musimy użyć print("sys.version: {}".format(version)).
Marco

@Marco, prawda. formatowanie łańcucha jest wykonywane dla wersji 3+ z argumentami słów kluczowych. można wykonać jako print („[{}, {}, {}]”. format (1,2,3)) dla python 2.7 ref: stackoverflow.com/questions/517355/string-formatting-in-python
oetzi

1

sys.version_infonie wydaje się zwracać tupleod 3,7. Zwraca raczej specjalną klasę, więc wszystkie przykłady z użyciem krotek nie działają, przynajmniej dla mnie. Oto dane wyjściowe z konsoli python:

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

Przekonałem się, że użycie kombinacji sys.version_info.majori sys.version_info.minorwydaje się wystarczające. Na przykład,...

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

sprawdza, czy korzystasz z Python 3. Możesz nawet sprawdzić bardziej szczegółowe wersje za pomocą ...

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)

może sprawdzić, czy używasz przynajmniej Python 3.5.


To coś w rodzaju podklasy namedtuplei porównanie z krotką zdecydowanie działa. Aby uzyskać pełną równość, potrzebujesz pięcioelementowego pisma: major, minor, micro, releaselevel (string) i serial.
Michaił Edoshin

0

Jeszcze prostszy i najprostszy sposób:

W Spyder uruchom nową „konsolę IPython”, a następnie uruchom dowolny z istniejących skryptów.

Teraz wersję można zobaczyć na pierwszym wydruku wydrukowanym w oknie konsoli:

„Python 3.7.3 (domyślnie, 24 kwietnia 2019 r., 15:29:51) ...”

wprowadź opis zdjęcia tutaj


0

Aby sprawdzić z wiersza poleceń, w jednym poleceniu, ale w wersji major, minor, micro, poziom wydania i numer seryjny :

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

3.7.6-final-0

Uwaga: .format()zamiast f-stringów lub '.'.join()pozwala na użycie dowolnych znaków formatowania i separatorów, np. Aby uczynić to ciągiem wyrazów jednoznacznych. Umieszczam to w skrypcie narzędzia bash, który zgłasza wszystkie ważne wersje: python, numpy, pandy, sklearn, MacOS, xcode, clang, brew, conda, anaconda, gcc / g ++ itp. Przydatny do logowania, replikacji, rozwiązywania problemów itp. Zgłaszania błędów itp. .


-1

Jeśli pracujesz na Linuksie, po prostu daj polecenie python wyjściowe będzie wyglądać tak

Python 2.4.3 (nr 1, 11 czerwca 2009 r., 14:09:37)

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

Aby uzyskać więcej informacji, wpisz „pomoc”, „prawa autorskie”, „kredyty” lub „licencja”.


5
Chcę, aby mój skrypt Pythona mógł uzyskać wersję interpretującego go języka Python. Prawidłowa odpowiedź została zaakceptowana.
przewoźnik

Nie pomaga uzyskać Pythonwersji w skrypcie, również podobna odpowiedź już opublikowana wcześniej: stackoverflow.com/a/35294211/950762
Akif
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.