68 votes

Python gracieux des fonctionnalités futures (__future__ import

Comment avez-vous gérer harmonieusement échec des fonctionnalités futures importations? Si un utilisateur est en cours d'exécution à l'aide de Python 2.5 et la première instruction dans mon module est:

from __future__ import print_function

La compilation de ce module pour Python 2.5 échouera avec un:

  File "__init__.py", line 1
    from __future__ import print_function
SyntaxError: future feature print_function is not defined

Je tiens à informer l'utilisateur qu'ils ont besoin de relancer le programme avec Python >= 2.6 et peut-être donner quelques instructions sur la façon de le faire. Cependant, pour citer PEP 236:

Les seules lignes qui peuvent apparaître avant un future_statement sont:

  • Le module de docstring (le cas échéant).
  • Commentaires.
  • Des lignes vides.
  • D'autres future_statements.

Donc je ne peux pas faire quelque chose comme:

import __future__

if hasattr(__future__, 'print_function'):
    from __future__ import print_function
else:
    raise ImportError('Python >= 2.6 is required')

Parce qu'il donne:

  File "__init__.py", line 4
    from __future__ import print_function
SyntaxError: from __future__ imports must occur at the beginning of the file

Cet extrait de la PEP semble donner de l'espoir de le faire en ligne:

Q: je veux enrouler future_statements dans les blocs try/except, donc je peux l'utiliser code différent selon l' la version de Python, je suis en cours d'exécution. Pourquoi ne puis-je pas?

A: Désolé! try/except est un moteur d'exécution fonctionnalité; future_statements sont surtout au moment de la compilation de gadgets, et votre try/except arrive longtemps après la compilateur est fait. C'est, par la fois que vous faites try/except, la sémantique en effet, pour le module sont déjà un fait accompli. Depuis le try/except ne pas accomplir ce qu'il semble comme il doit accomplir, c'est tout simplement pas autorisé. Nous voulons aussi garder ces déclarations spéciales très facile à les trouver et de les reconnaître.

Notez que vous pouvez importer __future__ directement, et d'utiliser l'information dans il, avec sys.version_info, à la figure où l'édition que vous êtes l'exécution en vertu de l'est à l'égard d'un compte tenu de la fonction d'état.

Des idées?

60voto

S.Lott Points 207588

"Je tiens à informer l'utilisateur qu'ils ont besoin de relancer le programme avec Python >= 2.6 et peut-être donner quelques instructions sur la façon de le faire."

N'est-ce pas un fichier lisez-moi est-ce?

Voici votre solution de rechange. Un "wrapper": une petite goutte de Python qui vérifie l'environnement avant de lancer votre cible aop.

Fichier: appwrapper.py

import sys
major, minor, micro, releaselevel, serial = sys.version_info
if (major,minor) <= (2,5):
    # provide advice on getting version 2.6 or higher.
    sys.exit(2)
import app
app.main()


Ce "importation directe" signifie. Vous pouvez examiner le contenu de __future__. Vous êtes encore lié par le fait que l'un from __future__ import print_function est une information pour le compilateur, mais vous pouvez fouiller avant d'importer le module qui fait le vrai travail.

import __future__, sys
if "print_function" in __future__: 
    # Could also check sys.version_info >= __future__. print_function.optional
    import app
    app.main()
else:
    print "instructions for upgrading"

46voto

Scott Griffiths Points 8867

Plutôt hacky mais simple méthode que j'ai utilisé avant est d'exploiter le fait que l'octet littéraux ont été introduites dans la version 2.6 de Python et d'utiliser quelque chose comme ceci près le début du fichier:

b'This module needs Python 2.6 or later. Please do xxx.'

C'est sans danger en Python 2.6 ou plus tard, mais un SyntaxError dans les versions antérieures. Toute personne essayant de compiler votre fichier va encore faire une erreur, mais ils reçoivent aussi le message que l'on veut donner.

Vous pourriez penser que vous devez avoir cette ligne après votre from __future__ import print_function , puis il sera à l'importation qui génère l' SyntaxError - et vous n'aurez pas la chance de voir la durée de message d'erreur, mais, curieusement, les plus tard, l'erreur est prioritaire. Je soupçonne que l'erreur de l'import n'est pas vraiment une erreur de syntaxe, en soi, elle n'est pas soulevée sur la première compilation passer, et si réel les erreurs de syntaxe soulevées premier (mais je suppose).

Cela pourrait ne pas vous rencontrer les critères pour être "gracieux", et c'est très Python 2.6 spécifiques, mais il est rapide et facile à faire.

40voto

Dave Burton Points 825

Il suffit de mettre un commentaire sur la même ligne avec l' "from __future__ import ...", comme ceci:

from __future__ import print_function, division  # We require Python 2.6 or later

Depuis Python affiche la ligne contenant l'erreur, si vous essayez d'exécuter le module avec Python 2.5, vous obtiendrez une belle description de l'erreur:

    from __future__ import print_function, division  # We require Python 2.6 or later
SyntaxError: future feature print_function is not defined

-3voto

DevPlayer Points 996

Une façon de gérer harmonieusement échoué __ future __ les importations est de les éviter un tête de temps complètement.

L'exécutable python ou python.exe a un -V (c'est capital vee) argument de ligne de commande qui retourne une chaîne de caractères sur la sortie stderr dans le format "Python 2.7", ou qui jamais la version que vous avez.

Il y a des avantages à tester la version de Python avant de charger un script Python/module/package/etc.

Google pour certains DOS des scripts que j'ai écrit pour un exemple complexe.

Python: le Meilleur moyen de vérifier la version de Python dans le programme qui utilise les nouvelles fonctionnalités de la langue?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X