Comment puis-je vérifier la version de Python dans un programme qui utilise de nouvelles fonctionnalités de langage?

si j'ai un script Python qui nécessite au moins un la version de Python, quelle est la bonne façon d'échouer gracieusement quand une version antérieure de Python est utilisée pour lancer le script?

Comment puis-je obtenir le contrôle assez tôt pour émettre un message d'erreur et la sortie?

par exemple, j'ai un programme qui utilise l'opérateur ternery (nouveau en 2.5) et" avec " blocs (2.6). J'ai écrit une simple petite version d'interprète. le vérificateur de routine qui est la première chose que le script serait appeler. .. sauf qu'il n'est pas loin. Au lieu de cela, l' script échoue lors de la compilation python, avant mes routines sont même appelés. Ainsi, l'utilisateur du script voit certains très les tracebacks d'erreur synax obscure-qui exigent un expert pour en déduire que c'est simplement le cas de courir la mauvaise version de Python.

je sais comment vérifier la version de Python. Le problème est qu'une certaine syntaxe est illégale dans les anciennes versions de Python. Considérez ce programme:

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

en cas d'exécution sous 2.4, je veux ce résultat

$ ~/bin/python2.4 tern.py 
must use python 2.5 or greater

et non ce résultat:

$ ~/bin/python2.4 tern.py 
  File "tern.py", line 5
    x = 1 if True else 2
           ^
SyntaxError: invalid syntax

(canalisation pour un collaborateur.)

231
demandé sur Martin Thoma 2009-01-15 11:45:28

17 réponses

vous pouvez tester en utilisant eval :

try:
  eval("1 if True else 2")
except SyntaxError:
  # doesn't have ternary

aussi, with est disponible en Python 2.5, il suffit d'ajouter from __future__ import with_statement .

EDIT: pour obtenir le contrôle assez tôt, vous pouvez le diviser en différents fichiers .py et vérifier la compatibilité dans le fichier principal avant l'importation (par exemple dans __init__.py dans un paquet):

# __init__.py

# Check compatibility
try:
  eval("1 if True else 2")
except SyntaxError:
  raise ImportError("requires ternary support")

# import from another module
from impl import *
104
répondu orip 2017-05-31 15:35:48

avoir une enveloppe autour de votre programme qui fait ce qui suit.

import sys

req_version = (2,5)
cur_version = sys.version_info

if cur_version >= req_version:
   import myApp
   myApp.run()
else:
   print "Your Python interpreter is too old. Please consider upgrading."

vous pouvez également utiliser sys.version() , si vous prévoyez de rencontrer des personnes qui utilisent des interprètes Python pré-2.0, mais alors vous avez quelques expressions régulières à faire.

et il pourrait y avoir des façons plus élégantes de le faire.

102
répondu Ed Carrel 2012-07-12 17:45:44

Essayer

import platform
platform.python_version()

Devrait vous donner une chaîne comme "2.3.1". Si ce n'est pas exactement ce que vous voulez il y a un riche ensemble de données disponibles à travers la "plate-forme" build-in. Ce que tu veux devrait être quelque part.

28
répondu James Anderson 2009-01-15 09:08:12

Probablement la meilleure façon de faire cette comparaison de version est d'utiliser le sys.hexversion . C'est important parce que comparer la version tuples ne vous donnera pas le résultat désiré dans toutes les versions de python.

import sys
if sys.hexversion < 0x02060000:
    print "yep!"
else:
    print "oops!"
21
répondu sorin 2010-06-28 12:38:59
import sys    
# prints whether python is version 3 or not
python_version = sys.version_info.major
if python_version == 3:
    print("is python 3")
else:
    print("not python 3")
15
répondu Erick Wendel 2016-04-15 19:32:40

Réponse de Nykakin à AskUbuntu :

vous pouvez également vérifier la version Python à partir du code lui-même en utilisant le module platform de la bibliothèque standard.

il y a deux fonctions:

  • platform.python_version() (renvoie la chaîne).
  • platform.python_version_tuple() (renvoie tuple).

les Code Python

créer un fichier par exemple: version.py )

méthode facile pour vérifier la version:

import platform

print(platform.python_version())
print(platform.python_version_tuple())

vous pouvez également utiliser la méthode eval :

try:
  eval("1 if True else 2")
except SyntaxError:
  raise ImportError("requires ternary support")

lancez le fichier Python en ligne de commande:

$ python version.py 
2.7.11
('2', '7', '11')

la sortie de Python avec CGI via un serveur WAMP sur Windows 10:

Screenshot 2016-11-16 14.39.01 by Suriyaa Kudo


ressources utiles

9
répondu Suriyaa 2017-12-23 22:09:37

Sets est devenu une partie du langage de base en Python 2.4, afin de rester compatible à l'envers. Je l'ai fait à l'époque, ce qui vous conviendra aussi:

if sys.version_info < (2, 4):
    from sets import Set as set
7
répondu André 2012-07-12 17:46:38

bien que la question soit: Comment puis-je obtenir le contrôle assez tôt pour émettre un message d'erreur et quitter ?

la question à laquelle je réponds est: Comment puis-je obtenir le contrôle assez tôt pour émettre un message d'erreur avant de lancer l'application ?

je peux y répondre beaucoup différemment que les autres postes. Semble de réponses pour essayer de résoudre votre question de L'intérieur de Python.

je dis, faites une vérification de version avant de lancer Python. Je vois que votre chemin est Linux ou unix. Cependant, je ne peux vous offrir Qu'un script Windows. J'imagine que l'adapter à la syntaxe de script linux ne serait pas trop difficile.

voici le script DOS avec la version 2.7:

@ECHO OFF
REM see http://ss64.com/nt/for_f.html
FOR /F "tokens=1,2" %%G IN ('"python.exe -V 2>&1"') DO ECHO %%H | find "2.7" > Nul
IF NOT ErrorLevel 1 GOTO Python27
ECHO must use python2.7 or greater
GOTO EOF
:Python27
python.exe tern.py
GOTO EOF
:EOF

ceci n'exécute aucune partie de votre application et ne soulèvera donc pas d'Exception Python. Il ne crée pas de fichier temporaire ou d'ajouter tout Variables d'environnement OS. Et il ne se termine pas votre application à une exception due à des règles de syntaxe de version différentes. C'est trois points d'accès de sécurité en moins.

la ligne FOR /F est la clé.

FOR /F "tokens=1,2" %%G IN ('"python.exe -V 2>&1"') DO ECHO %%H | find "2.7" > Nul

pour plusieurs versions de python consulter l'url: http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=17

Et mon hack version:

[MS script; Python vérification de la version pré-lancement du module Python] http://pastebin.com/aAuJ91FQ

7
répondu DevPlayer 2018-05-02 03:39:26

comme indiqué ci-dessus, les erreurs de syntaxe se produisent au moment de la compilation et non au moment de l'exécution. Alors que Python est un "langage interprété", le code Python n'est pas en fait directement interprété; il est compilé en code octet, qui est ensuite interprété. Il y a une étape de compilation qui se produit lorsqu'un module est importé (s'il n'y a pas de version déjà compilée disponible sous la forme d'un .pyc ou .pyd) et c'est là que vous obtenez votre erreur, pas (tout à fait exactement) lorsque votre code est en cours d'exécution.

vous pouvez désactiver l'étape de compilation et la faire se produire à l'exécution pour une seule ligne de code, si vous le voulez, en utilisant eval, comme noté ci-dessus, mais je préfère personnellement éviter de le faire, parce qu'il provoque Python à effectuer potentiellement inutile compilation d'exécution, pour une chose, et pour une autre, il crée ce que pour moi se sent comme code clutter. (Si vous voulez, vous pouvez générer du code qui génère du code qui génère du code - et avoir un temps absolument fabuleux Modifier et déboguer que dans 6 mois à partir de maintenant.) Donc ce que je recommande à la place est quelque chose de plus comme ceci:

import sys
if sys.hexversion < 0x02060000:
    from my_module_2_5 import thisFunc, thatFunc, theOtherFunc
else:
    from my_module import thisFunc, thatFunc, theOtherFunc

.. ce que je ferais même si je n'avais qu'une fonction qui utilise une syntaxe plus récente et qui est très courte. (En fait, je prendrais toutes les mesures raisonnables pour réduire au minimum le nombre et la taille de ces fonctions. Je pourrais même écrire une fonction comme ifTrueAElseB (cond, a, b) Avec cette seule ligne de syntaxe.)

une autre chose qui pourrait valoir faisant remarquer (que je suis un peu étonné que personne ne l'a encore fait remarquer) que bien que les versions précédentes de Python ne supportaient pas le code comme

value = 'yes' if MyVarIsTrue else 'no'

..il a pris en charge le code comme

value = MyVarIsTrue and 'yes' or 'no'

C'était la vieille façon d'écrire les expressions ternaires. Je n'ai pas encore installé Python 3, mais pour autant que je sache, cette" vieille " manière fonctionne encore aujourd'hui, donc vous pouvez décider par vous-même si oui ou non cela vaut la peine d'utiliser la nouvelle syntaxe, si vous devez prendre en charge l'utilisation des anciennes versions de Python.

2
répondu Shavais 2011-09-13 02:27:02

mettez ce qui suit en haut de votre dossier:

import sys

if float(sys.version.split()[0][:3]) < 2.7:
    print "Python 2.7 or higher required to run this code, " + sys.version.split()[0] + " detected, exiting."
    exit(1)

puis continuer avec le code Python normal:

import ...
import ...
other code...
2
répondu jml 2015-10-23 11:19:29
import sys
sys.version

obtiendra réponse comme ceci

'2.7.6 (par défaut, Oct 26 2016, 20:30:19) \n [GCC 4.8.4]

ici 2.7.6 est la version

2
répondu Janarthanan Ramu 2017-05-24 05:26:49

je pense que la meilleure façon est de tester la fonctionnalité plutôt que les versions. Dans certains cas, cela est insignifiant, pas dans d'autres.

par exemple:

try :
    # Do stuff
except : # Features weren't found.
    # Do stuff for older versions.

aussi longtemps que vous êtes suffisamment précis dans l'utilisation des blocs try/except, vous pouvez couvrir la plupart de vos bases.

1
répondu sykora 2009-01-15 08:51:22

je viens de trouver cette question après une recherche rapide tout en essayant de résoudre le problème moi-même et j'ai trouvé un hybride basé sur quelques-unes des suggestions ci-dessus.

J'aime L'idée de DevPlayer d'utiliser un script d'enrubannage, mais l'inconvénient est que vous finissez par maintenir plusieurs enrubannage pour différents os, donc j'ai décidé d'écrire L'enrubannage en python, mais j'ai utilisé la même logique de base" grab the version by running the exe " et j'ai trouvé ça.

je pense que ça devrait marcher pour 2,5 et plus. Je l'ai testé sur 2.66, 2.7.0 et 3.1.2 sur Linux et 2.6.1 sur OS X jusqu'à présent.

import sys, subprocess
args = [sys.executable,"--version"]

output, error = subprocess.Popen(args ,stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
print("The version is: '%s'"  %error.decode(sys.stdout.encoding).strip("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLMNBVCXZ,.+ \n") )

Oui, je sais que la ligne finale de décodage / bande est horrible, mais je voulais juste saisir rapidement le numéro de version. Je vais affiner.

Cela fonctionne assez bien pour moi, pour l'instant, mais si quelqu'un peut l'améliorer (ou me dire pourquoi c'est une mauvaise idée), ce serait trop cool.

1
répondu Steve 2012-05-09 16:11:57

vous pouvez vérifier avec sys.hexversion ou sys.version_info .

sys.hexversion n'est pas très humain parce que c'est un nombre hexadécimal. sys.version_info est un tuple, donc c'est plus humain.

Vérifiez Python 3.6 ou plus récent avec sys.hexversion :

import sys, time
if sys.hexversion < 0x30600F0:
    print("You need Python 3.6 or greater.")
    for _ in range(1, 5): time.sleep(1)
    exit()

Vérifiez Python 3.6 ou plus récent avec sys.version_info :

import sys, time
if sys.version_info[0] < 3 and sys.version_info[1] < 6:
    print("You need Python 3.6 or greater.")
    for _ in range(1, 5): time.sleep(1)
    exit()

sys.version_info est plus humain-friendly, mais prend plus caractère. Je reccomenderais sys.hexversion , même si c'est moins humain.

j'espère que cela vous a aidé!

0
répondu Pb2007 2018-01-27 19:26:55

pour autonome scripts python, le module suivant docstring truc pour appliquer une version python (ici v2.7.x) fonctionne (testé sur *nix).

#!/bin/sh
''''python -V 2>&1 | grep -q 2.7 && exec python -u -- ""151900920"" ${1+"$@"}; echo "python 2.7.x missing"; exit 1 # '''

import sys
[...]

cela devrait gérer la disparition de l'exécutable python aussi bien que la dépendance à grep. Voir ici pour le contexte.

0
répondu akhan 2018-07-15 23:17:25

Que pensez-vous de ceci:

import sys

def testPyVer(reqver):
  if float(sys.version[:3]) >= reqver:
    return 1
  else:
    return 0

#blah blah blah, more code

if testPyVer(3.0) == 1:
  #do stuff
else:
  #print python requirement, exit statement
-2
répondu Pb2007 2018-01-23 00:12:01

le problème est assez simple. Vous avez vérifié si la version était inférieure à 2.4, pas inférieure à ou égale à . Donc si la version Python est 2.4, ce n'est pas moins que 2.4. Ce que vous auriez dû avoir était:

    if sys.version_info **<=** (2, 4):

, Non

    if sys.version_info < (2, 4):
-3
répondu Peter Mortensen 2012-07-12 17:48:06