A cosa serve __future__ in Python e come / quando usarlo e come funziona


694

__future__appare frequentemente nei moduli Python. Non capisco a cosa __future__serva e come / quando usarlo anche dopo aver letto il __future__documento di Python .

Qualcuno può spiegare con esempi?

Alcune risposte sull'utilizzo di base __future__che ho ricevuto sembravano corrette.

Tuttavia, devo capire un'altra cosa riguardo a come __future__funziona:

Il concetto più confuso per me è come una versione corrente di Python includa funzionalità per versioni future e come un programma che utilizza una funzionalità di una versione futura possa essere compilato con successo nell'attuale versione di Python.

Immagino che la versione attuale sia piena di potenziali funzionalità per il futuro. Tuttavia, le funzionalità sono disponibili solo utilizzando __future__perché non sono lo standard corrente. Fammi sapere se ho ragione.


10
Questa è la proposta originale per la dichiarazione futura. L'ho trovato utile per capire perché è lì in primo luogo e quindi quando e come usarlo seguire naturalmente. python.org/dev/peps/pep-0236
Jpaji Rajnish


3
Una dichiarazione futura è una direttiva per il compilatore secondo cui un modulo particolare dovrebbe essere compilato usando la sintassi o la semantica che saranno disponibili in una versione futura specificata di Python. La dichiarazione futura intende facilitare la migrazione alle versioni future di Python che introducono modifiche incompatibili al linguaggio. Consente l'utilizzo delle nuove funzionalità su base per modulo prima del rilascio in cui la funzionalità diventa standard.
shivam13juna,

Risposte:


384

Con __future__l'inclusione del modulo, puoi lentamente abituarti a modifiche incompatibili o a quelle che introducono nuove parole chiave.

Ad esempio, per utilizzare i gestori di contesto, è necessario eseguire l'operazione from __future__ import with_statement2.5, poiché la withparola chiave era nuova e non deve più essere utilizzata come nome di variabile. Per usarewith come parola chiave Python in Python 2.5 o precedente, dovrai utilizzare l'importazione dall'alto.

Un altro esempio è

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

Senza __future__roba, entrambiprint dichiarazioni verrebbero stampate1 .

La differenza interna è che senza tale importazione, /è mappato al __div__()metodo, mentre con esso __truediv__()viene utilizzato. (In ogni caso,// chiama__floordiv__() .)

A proposito print: printdiventa una funzione in 3.x, perdendo la sua proprietà speciale come parola chiave. Quindi è il contrario.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>

151
non dimenticare from __future__ import braces: p
mdeous

13
@zoogleflatt Se sei più un ragazzo di tabulazione, non conosci PEP 8. Si consiglia vivamente di non utilizzare le schede ...
glglgl

5
@glglgl Beh tecnicamente dice solo che sono preferiti. Non mi è stato del tutto chiaro dopo aver letto perché questo è esattamente, suppongo che sia necessario abbinare i livelli di rientro esattamente per rendere più pulito il codice?
Jpaji Rajnish,

4
@zoogleflatt Sicuramente ha anche a che fare con il fatto che la maggior parte delle persone usa 4 spazi per 1 livello di rientro, che per motivi di compatibilità una scheda equivale a 8 spazi e si sconsiglia di mescolare schede e spazi (resp., AFAIK, anche vietato in Py3)
glglgl

1
@whiteSkar Al momento non sono aggiornato con le versioni più recenti di python 3, ma suppongo che sia ancora in uso, solo che probabilmente non ne avrai bisogno con queste funzionalità piuttosto vecchie. In Python 3,print è sicuramente una funzione, ma potrebbero esserci altre funzionalità che potrebbero essere utilizzate __future__. (Modifica: consultare docs.python.org/3/library/__future__.html dove è ancora utilizzato.)
glglgl

195

Quando lo fai

from __future__ import whatever

In realtà non stai usando una importdichiarazione, ma una dichiarazione futura . Stai leggendo i documenti sbagliati, in quanto non stai effettivamente importando quel modulo.

Le dichiarazioni future sono speciali: cambiano il modo in cui viene analizzato il modulo Python, motivo per cui devono essere nella parte superiore del file. Danno un significato nuovo - o diverso - a parole o simboli nel tuo file. Dai documenti:

Una dichiarazione futura è una direttiva per il compilatore secondo cui un modulo particolare dovrebbe essere compilato usando la sintassi o la semantica che saranno disponibili in una versione futura specificata di Python. La dichiarazione futura ha lo scopo di facilitare la migrazione alle versioni future di Python che introducono modifiche incompatibili al linguaggio. Consente l'utilizzo delle nuove funzionalità su base per modulo prima del rilascio in cui la funzionalità diventa standard.

Se vuoi davvero importare il __future__modulo, fallo e basta

import __future__

e quindi accedervi come al solito.


4
Tecnicamente, è anche un'istruzione di importazione, poiché il nome pertinente è associato a una variabile locale. from __future__ import print_functionentrambi modificano il comportamento della printparola chiave e hanno un effetto di runtime equivalente aprint_function = __import__("__future__").print_function
pppery

112

__future__ è uno pseudo-modulo che i programmatori possono utilizzare per abilitare nuove funzionalità linguistiche che non sono compatibili con l'interprete corrente . Ad esempio, l'espressione 11/4attualmente valuta 2. Se il modulo in cui viene eseguito aveva abilitato la vera divisione eseguendo:

from __future__ import division

l'espressione 11/4valuterà 2.75. Importando il __future__modulo e valutando le sue variabili, puoi vedere quando una nuova funzionalità è stata aggiunta per la prima volta alla lingua e quando diventerà l'impostazione predefinita:

  >>> import __future__
  >>> __future__.division
  _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)

1
Quindi, in base alla versione di rilascio nelle variabili, se l'interprete sta utilizzando una versione successiva di quanto indicato, import __future__ xyzè un no-op?
Ray,

4
È in qualche modo analogo a un polyfill nel mondo dei browser
cs01

47

Può essere usato per usare funzionalità che appariranno nelle versioni più recenti pur avendo una versione precedente di Python.

Per esempio

>>> from __future__ import print_function

ti permetterà di usare printcome una funzione:

>>> print('# of entries', len(dictionary), file=sys.stderr)

29

Ci sono già delle ottime risposte, ma nessuna di esse affronta un elenco completo di ciò che __future__ dichiarazione attualmente supporta.

In parole povere, la __future__dichiarazione obbliga gli interpreti Python a utilizzare le nuove funzionalità del linguaggio.


Le funzionalità attualmente supportate sono le seguenti:

nested_scopes

Prima di Python 2.1, il codice seguente generava un NameError :

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

La from __future__ import nested_scopesdirettiva consentirà di abilitare questa funzione.

generators

Introdotte funzioni del generatore come quella qui sotto per salvare lo stato tra successive chiamate di funzione:

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

division

La divisione classica viene utilizzata nelle versioni Python 2.x. Ciò significa che alcune dichiarazioni di divisione restituiscono una ragionevole approssimazione della divisione ("divisione vera") e altre restituiscono il piano ("divisione piano"). A partire da Python 3.0, la divisione vera è specificata da x/y, mentre la divisione pavimento è specificata dax//y .

La from __future__ import divisiondirettiva impone l'uso della divisione di stile Python 3.0.

absolute_import

Consente alla parentesi di racchiudere più importistruzioni. Per esempio:

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

Invece di:

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

O:

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

with_statement

Aggiunge l'istruzione withcome parola chiave in Python per eliminare la necessità di try/finallyistruzioni. Gli usi comuni di questo sono quando si esegue l'I / O di file come:

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

print_function:

Forza l'uso della print()chiamata di funzione in stile parentesi di Python 3 invece dell'istruzione di print MESSAGEstile.

unicode_literals

Introduce la sintassi letterale per l' bytesoggetto. Significa che dichiarazioni come quelle bytes('Hello world', 'ascii')possono essere semplicemente espresse come b'Hello world'.

generator_stop

Sostituisce l'uso StopIterationdell'eccezione utilizzata all'interno delle funzioni del generatore con l' RuntimeErroreccezione.

Un altro uso non menzionato sopra è che l' __future__istruzione richiede anche l'uso di interpreti Python 2.1+ poiché l'utilizzo di una versione precedente genererà un'eccezione di runtime.


Riferimenti


Supponendo di essere offline come fa Python a sapere se è disponibile una versione futura? E come utilizza le funzionalità future se non hai installato la versione futura di Python sul tuo computer?
Mohsen Haddadi,

25

O è come dire "Dato che questo è Python v2.7, usa quella diversa funzione 'print' che è stata aggiunta anche a Python v2.7, dopo che è stata aggiunta in Python 3. Quindi la mia 'stampa' non sarà più dichiarazioni (ad es. stampa "messaggio") ma funzioni (ad es. stampa ("messaggio", opzioni). In questo modo quando il mio codice viene eseguito in Python 3, "stampa" non si interromperà. "

In

from __future__ import print_function

print_function è il modulo che contiene la nuova implementazione di 'print' secondo come si comporta in python v3.

Questo ha più spiegazioni: http://python3porting.com/noconv.html


2

Uno degli usi che ho trovato molto utile è il modulo print_functionfrom __future__.

In Python 2.7, volevo che i caratteri di diverse istruzioni di stampa fossero stampati sulla stessa riga senza spazi.

Può essere fatto usando una virgola (",") alla fine, ma aggiunge anche uno spazio extra. La precedente dichiarazione quando usata come:

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

Questo stamperà il valore di v_numogni iterazione in una singola riga senza spazi.


-4

Dopo Python 3.0 in poi, print non è più solo un'istruzione, è invece una funzione. ed è incluso in PEP 3105.

Inoltre penso che il pacchetto Python 3.0 abbia ancora queste funzionalità speciali. Vediamo la sua usabilità attraverso un tradizionale "programma Piramide" in 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:
*
**
***
****

Se utilizziamo la normale funzione di stampa, non saremo in grado di ottenere lo stesso risultato, poiché print () viene fornito con una nuova riga aggiuntiva. Quindi ogni volta che esegue il ciclo interno per, verrà stampato * sulla riga successiva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.