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.)
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 *
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.
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.
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!"
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")
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:
ressources utiles
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
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
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.
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...
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
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.
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.
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é!
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.
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
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):