¿Para qué se usa __future__ en Python y cómo / cuándo usarlo y cómo funciona?

693

__future__aparece frecuentemente en los módulos de Python. No entiendo para qué __future__sirve y cómo / cuándo usarlo incluso después de leer el __future__documento de Python .

¿Alguien puede explicar con ejemplos?

Algunas respuestas sobre el uso básico __future__que he recibido me parecieron correctas.

Sin embargo, necesito entender una cosa más sobre cómo __future__funciona:

El concepto más confuso para mí es cómo una versión actual de Python incluye características para futuras versiones, y cómo un programa que usa una característica de una versión futura se puede compilar con éxito en la versión actual de Python.

Supongo que la versión actual incluye características potenciales para el futuro. Sin embargo, las funciones están disponibles solo mediante el uso __future__porque no son el estándar actual. Avísame si tengo razón.

leslie
fuente
10
Esta es la propuesta original para la declaración futura. Me pareció útil para entender por qué está allí en primer lugar y, por lo tanto, cuándo y cómo usarlo es algo natural. python.org/dev/peps/pep-0236
Jpaji Rajnish
55
Básicamente es el equivalente a "Supongo que no estás listo para esto, pero a tus hijos les va a encantar" .
Jean-François Corbett
3
Una declaración futura es una directiva para el compilador de que un módulo en particular debe compilarse utilizando la sintaxis o la semántica que estará disponible en una versión futura especificada de Python. La declaración futura pretende facilitar la migración a futuras versiones de Python que introducen cambios incompatibles en el lenguaje. Permite el uso de las nuevas funciones por módulo antes del lanzamiento en el que la función se convierte en estándar.
shivam13juna

Respuestas:

384

Con __future__la inclusión del módulo, puede acostumbrarse lentamente a los cambios incompatibles o a los que introducen nuevas palabras clave.

Por ejemplo, para usar los administradores de contexto, tenía que hacerlo from __future__ import with_statementen 2.5, ya que la withpalabra clave era nueva y ya no debería usarse como nombres de variables. Para usar withcomo palabra clave de Python en Python 2.5 o anterior, necesitará usar la importación desde arriba.

Otro ejemplo es

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

Sin las __future__cosas, ambas printdeclaraciones se imprimirían 1.

La diferencia interna es que sin esa importación, /se asigna a la__div__() método, mientras que con él __truediv__()se utiliza. (En cualquier caso, //llamadas__floordiv__() ).

A propósito print: se printconvierte en una función en 3.x, perdiendo su propiedad especial como palabra clave. Entonces es al revés.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
glglgl
fuente
151
no se olvide from __future__ import braces: p
mdeous
13
@zoogleflatt Si eres más un tipo de pestaña, no conoces PEP 8. Se recomienda encarecidamente no usar pestañas ...
glglgl
55
@glglgl Bueno, técnicamente solo dice que son preferidos. No estaba del todo claro para mí después de leer por qué esto es exactamente, supongo que es hacer que los niveles de sangría coincidan exactamente para que el código sea más ordenado.
Jpaji Rajnish
44
@zoogleflatt Seguramente también tiene que ver con el hecho de que la mayoría de las personas usan 4 espacios para 1 nivel de sangría, que por razones de compatibilidad una pestaña es equivalente a 8 espacios y se desaconseja mezclar pestañas y espacios (resp., AFAIK, incluso no se permite Py3)
glglgl
1
@whiteSkar Actualmente no estoy actualizado con las versiones más recientes de python 3, pero supongo que todavía está en uso, solo que probablemente no lo necesite con estas características bastante antiguas. En Python 3, printdefinitivamente es una función, pero puede haber otras características que podrían usar __future__. (Editar: ver docs.python.org/3/library/__future__.html donde todavía se usa.)
glglgl
195

Cuando tu lo hagas

from __future__ import whatever

En realidad no estás usando una importdeclaración, sino una declaración futura . Estás leyendo los documentos incorrectos, ya que en realidad no estás importando ese módulo.

Las declaraciones futuras son especiales: cambian la forma en que se analiza su módulo Python, por lo que deben estar en la parte superior del archivo. Le dan un significado nuevo o diferente a las palabras o símbolos en su archivo. De los documentos:

Una declaración futura es una directiva para el compilador de que un módulo en particular debe compilarse utilizando la sintaxis o la semántica que estará disponible en una versión futura especificada de Python. La declaración futura tiene la intención de facilitar la migración a futuras versiones de Python que introducen cambios incompatibles en el lenguaje. Permite el uso de las nuevas funciones por módulo antes del lanzamiento en el que la función se convierte en estándar.

Si realmente desea importar el __future__módulo, simplemente haga

import __future__

y luego acceda a él como de costumbre.

agf
fuente
44
Técnicamente, también es una declaración de importación, ya que el nombre relevante está vinculado a una variable local. from __future__ import print_functionambos cambian el comportamiento de la printpalabra clave y tienen un efecto de tiempo de ejecución equivalente aprint_function = __import__("__future__").print_function
pppery
112

__future__ es un pseudomódulo que los programadores pueden usar para habilitar nuevas funciones de lenguaje que no son compatibles con el intérprete actual . Por ejemplo, la expresión 11/4actualmente se evalúa como 2. Si el módulo en el que se ejecuta ha habilitado la verdadera división al ejecutar:

from __future__ import division

la expresión 11/4evaluaría a 2.75. Al importar el __future__módulo y evaluar sus variables, puede ver cuándo se agregó por primera vez una nueva característica al idioma y cuándo se convertirá en la predeterminada:

  >>> import __future__
  >>> __future__.division
  _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
CodeArtist
fuente
1
Entonces, según la versión de lanzamiento en las variables, si su intérprete está usando una versión posterior a la indicada, ¿ import __future__ xyzes un no-op?
Ray
44
Es algo análogo a un polyfill en el mundo del navegador
cs01
47

Se puede usar para usar funciones que aparecerán en versiones más nuevas mientras se tenga una versión anterior de Python.

Por ejemplo

>>> from __future__ import print_function

le permitirá usar printcomo una función:

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

Ya hay algunas respuestas excelentes, pero ninguna de ellas aborda una lista completa de lo que __future__ declaración admite actualmente.

En pocas palabras, la __future__declaración obliga a los intérpretes de Python a usar funciones más nuevas del lenguaje.


Las características que admite actualmente son las siguientes:

nested_scopes

Antes de Python 2.1, el siguiente código generaría un NameError :

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

La from __future__ import nested_scopesdirectiva permitirá que esta característica esté habilitada.

generators

Se introdujeron funciones generadoras como la siguiente para guardar el estado entre llamadas de función sucesivas:

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

division

La división clásica se usa en las versiones de Python 2.x. Lo que significa que algunas declaraciones de división devuelven una aproximación razonable de la división ("división verdadera") y otras devuelven el piso ("división del piso"). A partir de Python 3.0, la división verdadera se especifica por x/y, mientras que la división de piso se especifica porx//y .

La from __future__ import divisiondirectiva obliga al uso de la división de estilo Python 3.0.

absolute_import

Permite paréntesis para encerrar múltiples importdeclaraciones. Por ejemplo:

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

En vez de:

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

Agrega la declaración withcomo una palabra clave en Python para eliminar la necesidad de try/finallydeclaraciones. Los usos comunes de esto son al hacer E / S de archivos como:

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

print_function:

Fuerza el uso de la print()llamada a la función de estilo de paréntesis de Python 3 en lugar de la print MESSAGEdeclaración de estilo.

unicode_literals

Introduce la sintaxis literal para el bytesobjeto. Lo que significa que declaraciones como bytes('Hello world', 'ascii')pueden expresarse simplemente como b'Hello world'.

generator_stop

Reemplaza el uso de la StopIterationexcepción utilizada dentro de las funciones del generador con la RuntimeErrorexcepción.

Otro uso no mencionado anteriormente es que la __future__declaración también requiere el uso de intérpretes Python 2.1+ ya que el uso de una versión anterior generará una excepción en tiempo de ejecución.


Referencias

Robert Grossman
fuente
Suponiendo que está desconectado, ¿cómo sabe Python si hay una versión futura disponible o no? ¿Y cómo usa las funciones futuras si no ha instalado una versión futura de python en su computadora?
Mohsen Haddadi
25

¿O es como decir "Dado que esto es python v2.7, use esa función diferente 'imprimir' que también se ha agregado a python v2.7, después de que se agregó en python 3. Entonces mi 'impresión' ya no será declaraciones (p. ej., print "message") pero funciona (p. ej., print ("message", options). De esa manera, cuando mi código se ejecute en python 3, 'print' no se romperá ".

En

from __future__ import print_function

print_function es el módulo que contiene la nueva implementación de 'print' según cómo se comporta en python v3.

Esto tiene más explicación: http://python3porting.com/noconv.html

Praym
fuente
2

Uno de los usos que me pareció muy útil es el módulo print_functionfrom __future__.

En Python 2.7, quería que los caracteres de diferentes declaraciones de impresión se imprimieran en la misma línea sin espacios.

Se puede hacer usando una coma (",") al final, pero también agrega un espacio extra. La declaración anterior cuando se usa como:

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

Esto imprimirá el valor de v_numcada iteración en una sola línea sin espacios.

Abhi31jeet
fuente
-3

Después de Python 3.0 en adelante, imprimir ya no es solo una declaración, sino una función. y está incluido en PEP 3105.

También creo que el paquete Python 3.0 todavía tiene estas funcionalidades especiales. Veamos su usabilidad a través de un "programa Pyramid" tradicional 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 usamos la función de impresión normal, no podremos lograr el mismo resultado, ya que print () viene con una nueva línea adicional. Por lo tanto, cada vez que se ejecute el bucle for interno, se imprimirá * en la siguiente línea.

vikash gupta
fuente