Comment vérifier quelle version de Python exécute mon script?

1186

Comment puis-je vérifier quelle version de l'interpréteur Python interprète mon script?

transporteur
la source
1
Le fil de discussion actuel concerne la vérification de la version de python à partir d'un programme / script python. Dans le cas où vous cherchez à vérifier la version de l'interpréteur python installé sur votre machine à partir de la ligne de commande, veuillez vous référer au post suivant - Quelle version de Python ai-je installée?
RBT
1
voici une façon amusante de séparer python 3 et 2 ...python_version = int(str(range(3))[-2])
Chris_Rands
@RBT: pour une vérification en ligne à partir de la ligne de commande, voir ma réponse .
smci

Réponses:

1380

Ces informations sont disponibles dans la chaîne sys.version du module sys :

>>> import sys

Lisible par l'homme:

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

Pour un traitement ultérieur:

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

Pour vous assurer qu'un script s'exécute avec une version minimale requise de l'interpréteur Python, ajoutez ceci à votre code:

assert sys.version_info >= (2, 5)

Cela compare les informations de version majeure et mineure. Ajouter micro (= 0, 1etc.) et même releaselevel (= 'alpha', 'final'etc.) au tuple que vous aimez. Notez cependant qu'il est presque toujours préférable de vérifier "duck" si une certaine fonctionnalité est là, et sinon, une solution de contournement (ou renflouement). Parfois, les fonctionnalités disparaissent dans les nouvelles versions, remplacées par d'autres.

krawyoti
la source
39
c'est en fait la syntaxe de l'impression. pas pour vérifier la version. j'utilise cela dans mes scripts python 2 et 3:PY3 = sys.version_info[0] == 3
gcb
5
PY2 = sys.version_info [0] == 2 PY3 = sys.version_info [0] == 3
xiaoweiz
25
Vous pouvez également accéder à certains des champs en sys.version_infotant que propriétés, ce qui PY3 = sys.version_info.major == 3pourrait être un peu plus attrayant.
krs013
1
Remarque: sys.hexversion est comparé à 0x020502F0, voir docs.python.org/2/library/sys.html#sys.hexversion
Yinon Ehrlich
1
@gcb votre extrait de code se cassera chaque fois que Python 4 se produira. Tu devrais faire if sys.version_info >= (3,). Il est totalement pythonique de comparer des tuples de différentes tailles et cela fera la bonne chose.
Boris
373

Depuis la ligne de commande (notez le «V» majuscule):

python -V

Ceci est documenté dans 'man python'.

jcolino
la source
13
le capital V est la version, pas les minuscules
Rogue
96

J'aime sys.hexversionpour des trucs comme ça.

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

>>> import sys
>>> sys.hexversion
33883376
>>> '%x' % sys.hexversion
'20504f0'
>>> sys.hexversion < 0x02060000
True
brianz
la source
C'est une fonctionnalité intéressante de la version que je n'avais pas vue, et un peu plus facile à utiliser (au moins pour moi) que la version régulière ...
Wayne Werner
6
@sorin: pouvez-vous expliquer en quoi c'est mieux que par exemple la réponse de Seth? Puisque vous dites que c'est le meilleur, je me demande.
0xC0000022L
3
@ 0xC0000022L Vous êtes-vous déjà demandé comment vous pourriez comparer le texte du tuple? Comment «final» se compare-t-il à la version bêta, rc ou quoi que ce soit. Au lieu de cela, si vous avez une valeur numérique, vous pourrez toujours spécifier une version exacte.
sorin
1
@sorin: euh, ça n'a pas vraiment d'importance, n'est-ce pas? Si je compare contre (2,6,4)la 'final'ne semble pas affecter la comparaison et il est pas censé. Apparemment, aucun découpage n'est nécessaire lorsque je compare les parties "les plus importantes" du tuple. Cela semble être la façon dont il est traité et c'est ce que ma question portait. Je ne dis pas que cette solution n'a pas son mérite, je me demande simplement pourquoi c'est la meilleure - c'est-à-dire ce qui me manque.
0xC0000022L
11
Le niveau de sortie est défini comme étant «alpha», «bêta», «candidat» ou «final» qui se trouve également être comparé correctement ...
Fredrik
65

Votre meilleur pari est probablement quelque chose comme ça:

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

De plus, vous pouvez toujours encapsuler vos importations dans un simple essai, ce qui devrait détecter les erreurs de syntaxe. Et, au point de @ Heikki, ce code sera compatible avec des versions beaucoup plus anciennes de python:

>>> try:
...     from my_module import twoPointSixCode
... except Exception: 
...     print "can't import, probably because your python is too old!"
>>>
Seth
la source
3
Pourquoi une simple exception et non une erreur d'importation? : P
mortel
4
@deadly - ImportError n'attrapera pas les SyntaxErrors, qui seront levées si vous essayez d'utiliser une nouvelle syntaxe dans un vieux python, comme essayer d'utiliser le raccourci conditionnel dans la version antérieure à 2.5.
Seth
except Exceptionest trop large. Ne serait-il pas préférable d'utiliser des exceptions spécifiques auxquelles vous vous attendez?
Fermi paradox
1
@Fermiparadox - Être large maintient les hypothèses basses. La except Exception:ligne en elle-même suppose déjà un python moderne (2.x +). Peut-être qu'un futur python réorganisera les noms d'exceptions d'une manière incompatible en amont? (Probablement pas, mais qui sait à quoi ressemblera le python dans 20 ans lorsque nous aurons tous des implants oculaires oculus rift? Le code dure longtemps.)
Seth
65

Utilisez platform« spython_version du stdlib:

>>> from platform import python_version
>>> print(python_version())
2.7.8
Facture
la source
5
Pour la fonction d'impression, ce serait mieux entre parenthèses, pensé à la compatibilité. Si quelqu'un utilise sample dans la version 3, une erreur de syntaxe sera là en attente.
Alex Chiang
47

Mettez quelque chose comme:

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

en haut de votre script.

Notez que selon ce qui se trouve dans votre script, les anciennes versions de python que la cible peuvent ne pas être en mesure de charger le script, donc n'iront pas assez loin pour signaler cette erreur. Comme solution de contournement, vous pouvez exécuter ce qui précède dans un script qui importe le script avec le code plus moderne.

rjmunro
la source
6
Ceci est incorrect (ou du moins incomplet) parce que les anciens interprètes vont barf sur des constructions de langage plus récentes telles que x if Pred() else y. Ils mourront pendant la phase de "lexing" et n'auront jamais la chance de s'exécuter exit(1) . La réponse de Seth est correcte en encapsulant les nouvelles fonctionnalités du langage dans d'autres fichiers.
Mark Rushakoff
2
@MarkRushakoff: votre commentaire est déroutant. Quel aspect de cette réponse est faux? La elsebranche manquante ou pour laquelle un <est utilisé version_info? AFAIK Python ajoute des valeurs manquantes dans les tuples, et tout cela devrait être valide avant 2.6, non? La réponse de Seth utilise donc le découpage (redondant) alors que celui-ci ne le fait pas et cela rend votre commentaire encore plus confus.
0xC0000022L
5
Je pense que @MarkRushakoff dit que si vous avez ceci en haut d'un fichier, et une nouvelle fonctionnalité de langage ailleurs dans le même fichier, l'ancienne version de python mourra lors du chargement du fichier, avant d'exécuter tout cela, donc l'erreur ne sera pas affichée. Fondamentalement, vous devez placer ce qui précède (ou une autre vérification) en haut d'un fichier, puis importer le code qui nécessite une nouvelle version de python à partir de fichiers séparés.
rjmunro
1
Oui, ce que @rjmunro a dit :)
Mark Rushakoff
24

Voici une version courte en ligne de commande qui se ferme immédiatement (pratique pour les scripts et l'exécution automatisée):

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

Ou juste le majeur, le mineur et le micro:

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
la source
1
@vigilancer vous avez raison, au moment de la rédaction, ce n'était pas encore pertinent mais je l'ai mis à jour pour Python 3 maintenant :)
Wolph
Bien, cela résout mon problème où j'obtenais le numéro de version en capturant la sortie de python2 --versionet python3 --versiondepuis PHP. Alors que j'obtiendrais ce dernier sans problème via passthru(), le premier n'imprimerait qu'à l'écran mais ne serait jamais capturé, même lorsqu'il est redirigé dans un fichier ...
Tox
1
@tox Vous pouvez dire print() d'écrire dans un fichier si cela vous convient.
Wolph
Dans mon cas, ce serait plus ou moins que je redirige déjà la passthru()sortie vers un fichier. Votre solution fait exactement ce dont j'ai besoin. :)
Tox
14

Avec le sixmodule, vous pouvez le faire en:

import six

if six.PY2:
  # this is python2.x
else:
  # six.PY3
  # this is python3.x
Dzhuang
la source
8
import sys
sys.version.split(' ')[0]

sys.version vous donne ce que vous voulez, choisissez simplement le premier numéro :)

fengshaun
la source
4

Comme l'a dit Seth, le script principal pourrait vérifier sys.version_info(mais notez que cela n'apparaissait pas avant 2.0, donc si vous voulez prendre en charge les anciennes versions, vous devrez vérifier une autre propriété de version du module sys).

Mais vous devez toujours vous assurer de ne pas utiliser de fonctionnalités de langage Python dans le fichier qui ne sont pas disponibles dans les anciennes versions de Python. Par exemple, cela est autorisé dans Python 2.5 et versions ultérieures:

try:
    pass
except:
    pass
finally:
    pass

mais ne fonctionnera pas dans les anciennes versions de Python, car vous ne pouviez avoir que OU enfin correspondre à l'essai. Donc, pour la compatibilité avec les anciennes versions de Python, vous devez écrire:

try:
    try:
        pass
    except:
        pass
finally:
    pass
Heikki Toivonen
la source
4

La manière la plus simple

Tapez simplement python dans votre terminal et vous pouvez voir la version comme suit

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
la source
24
"La manière la plus simple" ... de faire quelque chose de différent de ce qui a été demandé.
Luc
2

Plusieurs réponses suggèrent déjà comment interroger la version actuelle de python. Pour vérifier par programme les exigences de version, j'utiliserais l'une des deux méthodes suivantes:

# 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
la source
2

Juste pour le plaisir, ce qui suit est une façon de le faire sur CPython 1.0-3.7b2, Pypy, Jython et Micropython. C'est plus une curiosité qu'une façon de le faire dans le code moderne. Je l'ai écrit dans le cadre de http://stromberg.dnsalias.org/~strombrg/pythons/ , qui est un script pour tester un extrait de code sur de nombreuses versions de python à la fois, afin que vous puissiez facilement avoir une idée de ce que python les fonctionnalités sont compatibles avec quelles versions de 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
la source
2

Si vous voulez détecter pré-Python 3 et ne voulez rien importer ...

... vous pouvez (ab) utiliser les changements de portée de compréhension de liste et le faire en une seule expression :

is_python_3_or_above = (lambda x: [x for x in [False]] and None or x)(True)
user541686
la source
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}")

production

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
oetzi
la source
Pour Python 2.7, nous devons utiliser print("sys.version: {}".format(version)).
Marco
@Marco, à droite. le formatage des chaînes est effectué pour v 3+ avec des arguments de mots clés. peut être fait comme impression ('[{}, {}, {}]'. format (1,2,3)) pour python 2.7 ref: stackoverflow.com/questions/517355/string-formatting-in-python
oetzi
1

Vérifiez la version Python: python -Vou python --versionouapt-cache policy python

vous pouvez également exécuter whereis pythonpour voir combien de versions sont installées.

Shusen Yi
la source
4
La même réponse a déjà été publiée. et, La question n'est pas "Comment vérifier quelle version de python j'ai installée?" mais "Comment vérifier la version dans mon script".
Stanley Kou
1

sys.version_infone semble pas retourner un en tupledate de 3.7. Au contraire, il renvoie une classe spéciale, donc tous les exemples utilisant des tuples ne fonctionnent pas, du moins pour moi. Voici la sortie d'une console python:

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

J'ai trouvé que l'utilisation d'une combinaison de sys.version_info.majoret sys.version_info.minorsemble suffire. Par exemple,...

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

vérifie si vous exécutez Python 3. Vous pouvez même rechercher des versions plus spécifiques avec ...

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)

peut vérifier si vous utilisez au moins Python 3.5.

Parker E.
la source
1
C'est quelque chose comme une sous-classe de namedtupleet la comparer avec le tuple fonctionne définitivement. Pour obtenir une égalité complète, vous avez besoin d'un type à cinq éléments: majeur, mineur, micro, releaselevel (chaîne) et série.
Mikhail Edoshin
1

Pour vérifier la version Python des commandes sous Windows, exécutez les commandes suivantes dans une invite de commande et vérifiez la sortie

c:\>python -V
Python 2.7.16

c:\>py -2 -V
Python 2.7.16

c:\>py -3 -V
Python 3.7.3

De plus, pour voir la configuration des dossiers pour chaque version de Python, exécutez les commandes suivantes:

For Python 2,'py -2 -m site'
For Python 3,'py -3 -m site'
Aamir M Meman
la source
-1

Si vous travaillez sur Linux, donnez simplement une python sortie de commande comme celle-ci

Python 2.4.3 (# 1, 11 juin 2009, 14:09:37)

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

Tapez "aide", "copyright", "crédits" ou "licence" pour plus d'informations.

pkm
la source
6
Je veux que mon script python puisse obtenir la version de python qui l'interprète. La bonne réponse a été acceptée.
porteur
Cela n'aide pas à obtenir la Pythonversion dans le script, également une réponse similaire déjà publiée auparavant: stackoverflow.com/a/35294211/950762
Akif
-1

La manière la plus simple et la plus simple:

Dans Spyder, démarrez une nouvelle "console IPython", puis exécutez l'un de vos scripts existants.

Maintenant, la version peut être vue dans la première sortie imprimée dans la fenêtre de la console:

"Python 3.7.3 (par défaut, 24 avril 2019, 15:29:51) ..."

entrez la description de l'image ici

S. Jessen
la source
-1

Pour vérifier à partir de la ligne de commande, en une seule commande, mais inclure la version majeure, mineure, micro, releaselevel et serial , puis appelez le même interpréteur Python (c'est-à-dire le même chemin) que celui que vous utilisez pour votre script:

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

3.7.6-final-0

Remarque: .format()au lieu de f-strings ou '.'.join()vous permet d'utiliser des caractères de formatage et de séparateur arbitraires, par exemple pour en faire une chaîne d'un mot greppable. Je mets cela dans un script utilitaire bash qui rapporte toutes les versions importantes: python, numpy, pandas, sklearn, MacOS, xcode, clang, brew, conda, anaconda, gcc / g ++ etc. .

smci
la source
Cette réponse serait appropriée pour une question différente, comme celle liée dans les commentaires sous la question. Il n'est pas approprié pour déterminer quelle version Python exécute un script à partir de ce script, car il n'y a aucune garantie que la pythoncommande appelle cet interpréteur Python particulier.
user2357112 prend en charge Monica il y a
@ user2357112supportsMonica: cette réponse correspond parfaitement à la question posée. La question, comme indiqué nulle part, dit "de l'intérieur du script". Si c'était le cas, ce serait différent. Clairement, cette réponse implique "invoquer le même interpréteur Python, c'est-à-dire le même chemin que celui que vous avez utilisé pour votre script". Mais si vous insistez, je dois le modifier dans la réponse, je le ferai.
smci il y a