O que é __future__ no Python usado e como / quando usá-lo e como funciona

693

__future__aparece frequentemente nos módulos Python. Eu não entendo o que __future__é e como / quando usá-lo, mesmo depois de ler o __future__documento do Python .

Alguém pode explicar com exemplos?

Algumas respostas sobre o uso básico __future__que recebi pareciam corretas.

No entanto, preciso entender mais uma coisa sobre como __future__funciona:

O conceito mais confuso para mim é como uma versão atual do python inclui recursos para versões futuras e como um programa que usa um recurso de uma versão futura pode ser compilado com êxito na versão atual do Python.

Eu estou supondo que a versão atual seja empacotada com recursos potenciais para o futuro. No entanto, os recursos estão disponíveis apenas pelo uso, __future__porque não são o padrão atual. Deixe-me saber se estou certo.

leslie
fonte
10
Esta é a proposta original para a declaração futura. Achei útil entender por que está lá em primeiro lugar, e quando e como usá-lo seguem naturalmente. python.org/dev/peps/pep-0236
Jpaji Rajnish, 02/03/2015
54
É basicamente o equivalente a "Eu acho que você não está pronto para isso, mas seus filhos vão adorar" .
Jean-François Corbett
3
Uma declaração futura é uma diretiva para o compilador de que um módulo específico deve ser compilado usando sintaxe ou semântica que estará disponível em uma versão futura especificada do Python. A declaração futura visa facilitar a migração para versões futuras do Python que introduzem alterações incompatíveis na linguagem. Permite o uso dos novos recursos por módulo antes do lançamento no qual o recurso se torna padrão.
shivam13juna

Respostas:

384

Com __future__a inclusão do módulo, você pode se acostumar lentamente a alterações incompatíveis ou a introduzir novas palavras-chave.

Por exemplo, para usar gerenciadores de contexto, você precisava fazer isso from __future__ import with_statementna versão 2.5, pois a withpalavra - chave era nova e não deveria mais ser usada como nome de variável. Para usar withcomo uma palavra-chave Python no Python 2.5 ou mais antiga, você precisará usar a importação de cima.

Outro exemplo é

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

Sem o __future__material, ambas as printinstruções seriam impressas 1.

A diferença interna é que, sem essa importação, /é mapeado para o __div__()método, enquanto ele __truediv__()é usado. (Em qualquer caso, //chamadas __floordiv__().)

Apropos print: printtorna - se uma função no 3.x, perdendo sua propriedade especial como uma palavra-chave. Portanto, é o contrário.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
glglgl
fonte
151
não se esqueça from __future__ import braces: p
mdeous
13
@zoogleflatt Se você é um cara mais guia, você não sabe o PEP 8. Ele é altamente recomendável para não usar guias ...
glglgl
5
@glglgl Bem, tecnicamente, apenas diz que eles são os preferidos. Não ficou totalmente claro para mim depois de ler por que isso é exatamente, acho que é preciso que os níveis de recuo correspondam exatamente para tornar o código mais limpo?
Jpaji Rajnish
4
@zoogleflatt Certamente também tem a ver com o fato de que a maioria das pessoas usa 4 espaços para 1 nível de recuo, que, por razões de compatibilidade, uma guia é equivalente a 8 espaços e a mistura de guias e espaços é desencorajada (resp., AFAIK, mesmo não permitido em Py3)
glglgl
1
@whiteSkar No momento, não estou atualizado com as versões mais recentes do python 3, mas presumo que ele ainda esteja em uso, apenas que você provavelmente não precisará dele com esses recursos bastante antigos. No Python 3, printé definitivamente uma função, mas pode haver outros recursos que podem ser usados __future__. (Edit: see docs.python.org/3/library/__future__.html onde ainda é usado.)
glglgl
195

Quando você faz

from __future__ import whatever

Na verdade, você não está usando uma importdeclaração, mas uma declaração futura . Você está lendo os documentos errados, pois não está realmente importando esse módulo.

As instruções futuras são especiais - elas mudam a maneira como seu módulo Python é analisado, e é por isso que elas devem estar no topo do arquivo. Eles dão um significado novo - ou diferente - às palavras ou símbolos do seu arquivo. Dos documentos:

Uma declaração futura é uma diretiva para o compilador de que um módulo específico deve ser compilado usando sintaxe ou semântica que estará disponível em uma versão futura especificada do Python. A declaração futura visa facilitar a migração para versões futuras do Python que introduzem alterações incompatíveis na linguagem. Permite o uso dos novos recursos por módulo antes do lançamento no qual o recurso se torna padrão.

Se você realmente deseja importar o __future__módulo, basta

import __future__

e depois acesse-o normalmente.

agf
fonte
4
Tecnicamente, também é uma declaração de importação, pois o nome relevante está vinculado a uma variável local. from __future__ import print_functiontanto altera o comportamento da printpalavra-chave e tem um tempo de execução afetar equivalente aprint_function = __import__("__future__").print_function
pppery
112

__future__ é um pseudo-módulo que os programadores podem usar para habilitar novos recursos de idioma que não são compatíveis com o intérprete atual . Por exemplo, a expressão 11/4atualmente é avaliada como 2. Se o módulo em que é executado ativou a divisão verdadeira executando:

from __future__ import division

a expressão 11/4seria avaliada como 2.75. Ao importar o __future__módulo e avaliar suas variáveis, é possível ver quando um novo recurso foi adicionado pela primeira vez ao idioma e quando ele se tornará o padrão:

  >>> import __future__
  >>> __future__.division
  _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
CodeArtist
fonte
1
Portanto, com base na versão de lançamento nas variáveis, se o seu intérprete estiver usando uma versão posterior à indicada, isso import __future__ xyznão é uma opção?
Raio
4
É um pouco análogo a um polyfill no mundo dos navegadores
cs01
47

Ele pode ser usado para usar recursos que aparecerão em versões mais recentes enquanto houver uma versão mais antiga do Python.

Por exemplo

>>> from __future__ import print_function

permitirá que você use printcomo uma função:

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

Já existem ótimas respostas, mas nenhuma delas trata de uma lista completa de quais __future__ declaração atualmente suporta.

Simplificando, a __future__declaração força os intérpretes Python a usar recursos mais recentes da linguagem.


Os recursos que ele suporta atualmente são os seguintes:

nested_scopes

Antes do Python 2.1, o código a seguir geraria um NameError :

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

A from __future__ import nested_scopesdiretiva permitirá que esse recurso seja ativado.

generators

Funções de gerador introduzidas, como a abaixo, para salvar o estado entre chamadas de função sucessivas:

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

division

A divisão clássica é usada nas versões do Python 2.x. Significando que algumas declarações de divisão retornam uma aproximação razoável da divisão ("divisão verdadeira") e outras retornam o piso ("divisão do piso"). A partir do Python 3.0, a divisão verdadeira é especificada por x/y, enquanto a divisão do piso é especificada porx//y .

A from __future__ import divisiondiretiva força o uso da divisão de estilo Python 3.0.

absolute_import

Permite que parênteses incluam várias importinstruções. Por exemplo:

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

Ao invés 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

Adiciona a instrução withcomo uma palavra-chave no Python para eliminar a necessidade de try/finallyinstruções. Usos comuns disso são ao executar E / S de arquivo, como:

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

print_function:

Força o uso da print()chamada de função no estilo parêntese do Python 3 em vez da print MESSAGEdeclaração de estilo.

unicode_literals

Introduz a sintaxe literal do bytesobjeto. Significando que declarações como bytes('Hello world', 'ascii')podem ser simplesmente expressas como b'Hello world'.

generator_stop

Substitui o uso da StopIterationexceção usada nas funções do gerador pela RuntimeErrorexceção.

Um outro uso não mencionado acima é que a __future__instrução também requer o uso de intérpretes Python 2.1+, pois o uso de uma versão mais antiga gera uma exceção de tempo de execução.


Referências

Robert Grossman
fonte
Supondo que você esteja offline, como o python sabe se uma versão futura está disponível ou não? E como ele usa recursos futuros se você não instalou a versão futura do python no seu computador?
Mohsen Haddadi
25

Ou é como dizer "Como esse é o python v2.7, use a função 'print' diferente que também foi adicionada ao python v2.7, depois que foi adicionada no python 3. Portanto, meu 'print' não será mais uma declaração (por exemplo, print "message"), mas funciona (por exemplo, print ("message", options). Dessa forma, quando meu código é executado no python 3, 'print' não será interrompido. "

No

from __future__ import print_function

print_function é o módulo que contém a nova implementação de 'print', como está se comportando no python v3.

Isso tem mais explicações: http://python3porting.com/noconv.html

Praym
fonte
2

Um dos usos que eu achei muito úteis é o módulo print_functionfrom __future__.

No Python 2.7, eu queria que caracteres de diferentes instruções de impressão fossem impressos na mesma linha sem espaços.

Isso pode ser feito usando uma vírgula (",") no final, mas também acrescenta um espaço extra. A declaração acima quando usada como:

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

Isso imprimirá o valor de v_numcada iteração em uma única linha sem espaços.

Abhi31jeet
fonte
-3

Após o Python 3.0 em diante, print não é mais apenas uma declaração, é uma função. e está incluído no PEP 3105.

Também acho que o pacote Python 3.0 ainda possui essas funcionalidades especiais. Vamos ver sua usabilidade através de um "programa Pyramid" tradicional em 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 usarmos a função de impressão normal, não conseguiremos obter a mesma saída, pois print () vem com uma nova linha extra. Assim, sempre que o loop for interno for executado, ele será impresso * na próxima linha.

vikash gupta
fonte