À quoi sert __future__ en Python et comment / quand l'utiliser, et comment cela fonctionne

693

__future__apparaît fréquemment dans les modules Python. Je ne comprends pas à quoi __future__ça sert et comment / quand l'utiliser même après avoir lu le __future__doc de Python .

Quelqu'un peut-il expliquer avec des exemples?

Quelques réponses concernant l'utilisation de base de __future__J'ai reçu semblaient correctes.

Cependant, je dois comprendre une dernière chose concernant le __future__fonctionnement:

Le concept le plus déroutant pour moi est de savoir comment une version actuelle de python comprend des fonctionnalités pour les futures versions, et comment un programme utilisant une fonctionnalité d'une future version peut être compilé avec succès dans la version actuelle de Python.

Je suppose que la version actuelle est emballée avec des fonctionnalités potentielles pour l'avenir. Cependant, les fonctionnalités ne sont disponibles qu'en utilisant __future__car elles ne sont pas la norme actuelle. Faites-moi savoir si j'ai raison.

leslie
la source
10
Il s'agit de la proposition originale pour la future déclaration. Je l'ai trouvé utile pour comprendre pourquoi il est là en premier lieu et donc quand et comment l'utiliser suivent naturellement. python.org/dev/peps/pep-0236
Jpaji Rajnish
55
C'est essentiellement l'équivalent de "je suppose que vous n'êtes pas prêt pour cela, mais vos enfants vont adorer" .
Jean-François Corbett
3
Une future déclaration est une directive au compilateur selon laquelle un module particulier doit être compilé en utilisant la syntaxe ou la sémantique qui seront disponibles dans une future version spécifiée de Python. La future déclaration vise à faciliter la migration vers les futures versions de Python qui introduisent des modifications incompatibles dans le langage. Il permet l'utilisation des nouvelles fonctionnalités par module avant la version dans laquelle la fonctionnalité devient standard.
shivam13juna

Réponses:

384

Avec __future__l'inclusion du module, vous pouvez lentement vous habituer à des changements incompatibles ou à de tels changements introduisant de nouveaux mots clés.

Par exemple, pour utiliser les gestionnaires de contexte, vous deviez le faire from __future__ import with_statementen 2.5, car le withmot - clé était nouveau et ne devrait plus être utilisé comme nom de variable. Pour l'utiliser withcomme mot-clé Python dans Python 2.5 ou une version antérieure, vous devrez utiliser l'importation par le haut.

Un autre exemple est

from __future__ import division
print 8/7  # prints 1.1428571428571428
print 8//7 # prints 1

Sans le __future__truc, les deux printdéclarations s'imprimeraient 1.

La différence interne est que sans cette importation, /est mappé à la __div__()méthode, tandis qu'avec elle, __truediv__()est utilisé. (Dans tous les cas, //appelle __floordiv__().)

Apropos print: printdevient une fonction dans 3.x, perdant sa propriété spéciale comme mot-clé. C'est donc l'inverse.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
glglgl
la source
151
n'oubliez pas from __future__ import braces: p
mdeous
13
@zoogleflatt Si vous êtes plutôt du genre tab, vous ne connaissez pas PEP 8. Il est fortement recommandé de ne pas utiliser les onglets ...
glglgl
5
@glglgl Eh bien, techniquement, cela dit simplement qu'ils sont préférés. Ce n'était pas tout à fait clair pour moi après avoir lu pourquoi c'est exactement, je suppose que c'est d'avoir des niveaux de retrait correspondant exactement pour rendre le code plus net?
Jpaji Rajnish
4
@zoogleflatt Cela a sûrement aussi à voir avec le fait que la plupart des gens utilisent 4 espaces pour 1 niveau d'indentation, que pour des raisons de compatibilité un onglet équivaut à 8 espaces et que le mélange des onglets et des espaces est déconseillé (resp., AFAIK, même interdit dans Py3)
glglgl
1
@whiteSkar Je ne suis actuellement pas à jour avec les nouvelles versions de python 3, mais je suppose qu'il est toujours utilisé, juste que vous n'en avez probablement pas besoin avec ces fonctionnalités assez anciennes. En Python 3, printc'est certainement une fonction, mais il peut y avoir d'autres fonctionnalités qui pourraient être utilisées __future__. (Modifier: voir docs.python.org/3/library/__future__.html où il est encore utilisé.)
glglgl
195

Quand tu fais

from __future__ import whatever

Vous n'utilisez pas réellement une importdéclaration, mais une future déclaration . Vous lisez les mauvais documents, car vous n'importez pas réellement ce module.

Les futures instructions sont spéciales - elles changent la façon dont votre module Python est analysé, c'est pourquoi elles doivent être en haut du fichier. Ils donnent un sens nouveau - ou différent - aux mots ou symboles de votre fichier. De la documentation:

Une future déclaration est une directive au compilateur selon laquelle un module particulier doit être compilé en utilisant la syntaxe ou la sémantique qui seront disponibles dans une future version spécifiée de Python. La future déclaration vise à faciliter la migration vers les futures versions de Python qui introduisent des modifications incompatibles dans le langage. Il permet d'utiliser les nouvelles fonctionnalités par module avant la version dans laquelle la fonctionnalité devient standard.

Si vous voulez réellement importer le __future__module, faites simplement

import __future__

puis accédez-y comme d'habitude.

agf
la source
4
Techniquement, il s'agit également d'une instruction d'importation, car le nom correspondant est lié à une variable locale. from __future__ import print_functionles deux modifient le comportement du printmot - clé et ont un effet d'exécution équivalent àprint_function = __import__("__future__").print_function
pppery
112

__future__ est un pseudo-module que les programmeurs peuvent utiliser pour activer de nouvelles fonctionnalités de langage qui ne sont pas compatibles avec l'interpréteur actuel . Par exemple, l'expression est 11/4actuellement évaluée à 2. Si le module dans lequel il est exécuté avait permis une véritable division en exécutant:

from __future__ import division

l'expression 11/4serait évaluée à 2.75. En important le __future__module et en évaluant ses variables, vous pouvez voir quand une nouvelle fonctionnalité a été ajoutée pour la première fois à la langue et quand elle deviendra la valeur par défaut:

  >>> import __future__
  >>> __future__.division
  _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
CodeArtist
la source
1
Donc, en fonction de la version de sortie dans les variables, si votre interprète utilise une version ultérieure à celle indiquée, import __future__ xyzest-ce un non-op?
Ray
4
Il est quelque peu analogue à un polyfill dans le monde des navigateurs
cs01
47

Il peut être utilisé pour utiliser des fonctionnalités qui apparaîtront dans les versions plus récentes tout en ayant une ancienne version de Python.

Par exemple

>>> from __future__ import print_function

vous permettra d'utiliser printen fonction:

>>> print('# of entries', len(dictionary), file=sys.stderr)
Mihai Maruseac
la source
29

Il existe déjà d'excellentes réponses, mais aucune d'entre elles n'aborde une liste complète de __future__ déclaration prend actuellement en charge.

En termes simples, l' __future__instruction force les interprètes Python à utiliser les nouvelles fonctionnalités du langage.


Les fonctionnalités qu'il prend actuellement en charge sont les suivantes:

nested_scopes

Avant Python 2.1, le code suivant déclencherait une erreur NameError :

def f():
    ...
    def g(value):
        ...
        return g(value-1) + 1
    ...

La from __future__ import nested_scopesdirective permettra d'activer cette fonctionnalité.

generators

Introduction de fonctions de générateur telles que celle ci-dessous pour enregistrer l'état entre les appels de fonction successifs:

def fib():
    a, b = 0, 1
    while 1:
       yield b
       a, b = b, a+b

division

La division classique est utilisée dans les versions Python 2.x. Cela signifie que certaines déclarations de division renvoient une approximation raisonnable de la division ("vraie division") et d'autres renvoient le plancher ("division de l'étage"). À partir de Python 3.0, la véritable division est spécifiée par x/y, tandis que la division au sol est spécifiée par x//y.

La from __future__ import divisiondirective force l'utilisation de la division de style Python 3.0.

absolute_import

Permet aux parenthèses de joindre plusieurs importinstructions. Par exemple:

from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
    LEFT, DISABLED, NORMAL, RIDGE, END)

Au lieu de:

from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
    LEFT, DISABLED, NORMAL, RIDGE, END

Ou:

from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END

with_statement

Ajoute l'instruction en withtant que mot clé en Python pour éliminer le besoin d' try/finallyinstructions. Les utilisations courantes de ceci sont lors des E / S de fichiers telles que:

with open('workfile', 'r') as f:
     read_data = f.read()

print_function:

Force l'utilisation de l' print()appel de fonction de style parenthèse Python 3 au lieu de l' print MESSAGEinstruction de style.

unicode_literals

Présente la syntaxe littérale de l' bytesobjet. Cela signifie que des déclarations telles que bytes('Hello world', 'ascii')peuvent être simplement exprimées par b'Hello world'.

generator_stop

Remplace l'utilisation de l' StopIterationexception utilisée dans les fonctions du générateur par l' RuntimeErrorexception.

Une autre utilisation non mentionnée ci-dessus est que l' __future__instruction nécessite également l'utilisation d'interpréteurs Python 2.1+, car l'utilisation d'une ancienne version générera une exception d'exécution.


Références

Robert Grossman
la source
En supposant que vous êtes hors ligne, comment Python sait-il si une future version est disponible ou non? Et comment utilise-t-il les futures fonctionnalités si vous n'avez pas installé la future version de python sur votre ordinateur?
Mohsen Haddadi
25

Ou est-ce comme dire "Puisque c'est python v2.7, utilisez cette fonction 'print' différente qui a également été ajoutée à python v2.7, après avoir été ajoutée en python 3. Donc, mon 'print' ne sera plus des instructions (par exemple, print "message") mais fonctionne (par exemple, print ("message", options). De cette façon, lorsque mon code est exécuté en python 3, 'print' ne se cassera pas. "

Dans

from __future__ import print_function

print_function est le module contenant la nouvelle implémentation de 'print' selon la façon dont il se comporte en python v3.

Cela a plus d'explications: http://python3porting.com/noconv.html

Praym
la source
2

L'une des utilisations que j'ai trouvées très utiles est le module print_functionfrom __future__.

Dans Python 2.7, je voulais que les caractères de différentes instructions d'impression soient imprimés sur la même ligne sans espaces.

Cela peut être fait à l'aide d'une virgule (",") à la fin, mais il ajoute également un espace supplémentaire. L'instruction ci-dessus lorsqu'elle est utilisée comme:

from __future__ import print_function
...
print (v_num,end="")
...

Cela affichera la valeur de v_numchaque itération sur une seule ligne sans espaces.

Abhi31jeet
la source
-3

Après Python 3.0, print n'est plus seulement une instruction, c'est une fonction à la place. et est inclus dans PEP 3105.

Je pense également que le package Python 3.0 a toujours ces fonctionnalités spéciales. Voyons son utilité à travers un "programme Pyramid" traditionnel en Python:

from __future__ import print_function

class Star(object):
    def __init__(self,count):
        self.count = count

    def start(self):
        for i in range(1,self.count):
            for j in range (i): 
                print('*', end='') # PEP 3105: print As a Function 
            print()

a = Star(5)
a.start()

Output:
*
**
***
****

Si nous utilisons la fonction d'impression normale, nous ne pourrons pas obtenir la même sortie, car print () est livré avec une nouvelle ligne supplémentaire. Ainsi, chaque fois que la boucle for interne s'exécute, elle s'imprime * sur la ligne suivante.

vikash gupta
la source