Co to jest __future__ w Pythonie i jak / kiedy go używać i jak to działa

694

__future__często pojawia się w modułach Python. Nie rozumiem, co __future__jest i jak / kiedy go używać nawet po przeczytaniu pytona jest __future__doc .

Czy ktoś może wyjaśnić za pomocą przykładów?

Kilka odpowiedzi dotyczących podstawowego użycia __future__, które otrzymałem, wydawało się poprawnych.

Muszę jednak zrozumieć jeszcze jedną rzecz dotyczącą __future__działania:

Najbardziej mylące jest dla mnie pojęcie, w jaki sposób obecne wydanie Pythona zawiera funkcje dla przyszłych wydań oraz w jaki sposób program korzystający z funkcji z przyszłego wydania może zostać pomyślnie skompilowany w bieżącej wersji Pythona.

Domyślam się, że obecne wydanie zawiera potencjalne funkcje na przyszłość. Jednak funkcje są dostępne tylko przy użyciu, __future__ponieważ nie są bieżącym standardem. Daj mi znać, jeśli mam rację.

leslie
źródło
10
To jest oryginalna propozycja przyszłego oświadczenia. Uznałem, że jest to pomocne w zrozumieniu, dlaczego w ogóle istnieje, a więc kiedy i jak go używać, oczywiście. python.org/dev/peps/pep-0236
Jpaji Rajnish
55
Jest to w zasadzie odpowiednik „Myślę, że nie jesteś na to gotowy, ale twoje dzieci pokochają to” .
Jean-François Corbett,
3
Przyszłe oświadczenie to dyrektywa dla kompilatora, że ​​określony moduł powinien zostać skompilowany przy użyciu składni lub semantyki, które będą dostępne w określonej przyszłej wersji Pythona. Przyszła instrukcja ma na celu ułatwienie migracji do przyszłych wersji Pythona, które wprowadzają niezgodne zmiany w języku. Pozwala na korzystanie z nowych funkcji dla poszczególnych modułów przed wydaniem, w którym funkcja staje się standardem.
shivam13juna

Odpowiedzi:

384

Z __future__ dołączeniu modułu możesz powoli przyzwyczaić się do niezgodnych zmian lub do wprowadzania nowych słów kluczowych.

Na przykład, aby użyć menedżerów kontekstu, trzeba było zrobić from __future__ import with_statementw 2.5, jakowith słowo kluczowe było nowe i nie powinno być dłużej używane jako nazwy zmiennych. W celu wykorzystaniawith jako słowa kluczowego Python w Python 2.5 lub starszym, musisz użyć importu z góry.

Innym przykładem jest

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

Bez tych __future__rzeczy obaprint wydrukowano by oświadczenia 1.

Wewnętrzna różnica polega na tym, że bez tego importu /jest odwzorowywany na __div__()metodę, podczas gdy z nią __truediv__()jest używany. (W każdym razie //połączenia __floordiv__().)

Apropos print: printstaje się funkcją w 3.x, tracąc swoją specjalną właściwość jako słowo kluczowe. Tak jest na odwrót.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
glglgl
źródło
151
nie zapomnij from __future__ import braces: p
mdeous
13
@zoogleflatt Jeśli jesteś bardziej facetem od kart, nie znasz PEP 8. Zdecydowanie zaleca się, aby nie używać kart ...
glglgl
5
@glglgl Technicznie mówi po prostu, że są preferowane. Nie było dla mnie do końca jasne po przeczytaniu, dlaczego tak jest, domyślam się, że poziomy wcięcia są dokładnie dopasowane, aby kod był bardziej uporządkowany?
Jpaji Rajnish
4
@zoogleflatt Z pewnością ma to również związek z faktem, że większość ludzi używa 4 spacji na 1 poziom wcięcia, że ​​ze względów kompatybilności jedna tabulator odpowiada 8 spacjom i odradza się mieszanie tabulatorów i spacji (odpowiednio, AFAIK, nawet niedozwolone w Py3)
glglgl,
1
@whiteSkar Obecnie nie jestem na bieżąco z nowszymi wersjami Pythona 3, ale zakładam, że wciąż jest używany, tylko że prawdopodobnie nie potrzebujesz go z tymi dość starymi funkcjami. W Pythonie 3 printjest zdecydowanie funkcją, ale mogą istnieć inne funkcje, które mogą się przydać __future__. (Edytuj: patrz docs.python.org/3/library/__future__.html, gdzie jest nadal używany.)
glglgl
195

Kiedy to zrobisz

from __future__ import whatever

W rzeczywistości nie używasz importwyciągu, ale wyciąg w przyszłości . Czytasz złe dokumenty, ponieważ tak naprawdę nie importujesz tego modułu.

Przyszłe instrukcje są wyjątkowe - zmieniają sposób analizowania modułu Pythona, dlatego muszą znajdować się na górze pliku. Nadają nowe - lub inne - znaczenie słowom lub symbolom w twoim pliku. Z dokumentów:

Przyszłe oświadczenie to dyrektywa dla kompilatora, że ​​określony moduł powinien zostać skompilowany przy użyciu składni lub semantyki, które będą dostępne w określonej przyszłej wersji Pythona. Przyszła instrukcja ma na celu ułatwienie migracji do przyszłych wersji Pythona, które wprowadzają niezgodne zmiany w języku. Pozwala na korzystanie z nowych funkcji dla poszczególnych modułów przed wydaniem, w którym funkcja staje się standardem.

Jeśli naprawdę chcesz zaimportować __future__moduł, po prostu zrób

import __future__

a następnie uzyskaj do niego dostęp jak zwykle.

agf
źródło
4
Technicznie jest to również instrukcja importu, ponieważ odpowiednia nazwa jest powiązana ze zmienną lokalną. from __future__ import print_functionoba zmieniają zachowanie printsłowa kluczowego i mają wpływ na środowisko wykonawcze naprint_function = __import__("__future__").print_function
pppery
112

__future__ to pseudomoduł, którego programiści mogą używać do włączania nowych funkcji językowych, które nie są kompatybilne z bieżącym tłumaczem . Na przykład wyrażenie 11/4obecnie ocenia na 2. Jeśli moduł, w którym jest wykonywany, umożliwił prawdziwy podział, wykonując:

from __future__ import division

wyrażenie 11/4to ocenia 2.75. Importując __future__moduł i oceniając jego zmienne, możesz zobaczyć, kiedy po raz pierwszy dodano nową funkcję do języka i kiedy stanie się ona domyślną:

  >>> import __future__
  >>> __future__.division
  _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
CodeArtist
źródło
1
Tak więc, w oparciu o wersję wydania w zmiennych, jeśli Twój interpreter używa wersji późniejszej niż wskazuje, czy import __future__ xyzto nie jest możliwe?
Ray
4
Jest to nieco analogiczne do polifillu w świecie przeglądarek
cs01,
47

Można go używać do korzystania z funkcji, które pojawią się w nowszych wersjach, mając starszą wersję Pythona.

Na przykład

>>> from __future__ import print_function

pozwoli ci używać printjako funkcji:

>>> print('# of entries', len(dictionary), file=sys.stderr)
Mihai Maruseac
źródło
29

Istnieje już kilka świetnych odpowiedzi, ale żadna z nich nie odnosi się do pełnej listy tego, co __future__ oświadczenie obecnie obsługuje.

Mówiąc prościej, oświadczenie zmusza tłumaczy Python użyć nowszych funkcji języka.__future__


Funkcje, które obecnie obsługuje to:

nested_scopes

Przed wersją Python 2.1 następujący kod wywoływałby błąd NameError :

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

from __future__ import nested_scopesDyrektywa pozwoli tej funkcji była włączona.

generators

Wprowadzono funkcje generatora, takie jak ta poniżej, aby zapisać stan pomiędzy kolejnymi wywołaniami funkcji:

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

division

Klasyczny podział jest używany w wersjach Python 2.x. Oznacza to, że niektóre stwierdzenia podziału zwracają rozsądne przybliżenie podziału („podział prawdziwy”), a inne zwracają piętro („podział podłogi”). Począwszy od Python 3.0, prawdziwy podział jest określony przez x/y, podczas gdy podział podłogi jest określony przezx//y .

Do from __future__ import divisiondyrektywa wymusza stosowanie Python 3.0 stylu Division.

absolute_import

Pozwala na umieszczenie w nawiasie wielu importinstrukcji. Na przykład:

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

Zamiast:

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

Lub:

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

with_statement

Dodaje instrukcję withjako słowo kluczowe w Pythonie, aby wyeliminować potrzebę try/finallyinstrukcji. Typowe zastosowania tego są podczas wykonywania operacji we / wy pliku, takich jak:

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

print_function:

Wymusza użycie print()wywołania funkcji w nawiasie w stylu Python 3 zamiast instrukcji print MESSAGEstylu.

unicode_literals

Wprowadza dosłowną składnię dla bytesobiektu. Oznacza to, że takie stwierdzenia bytes('Hello world', 'ascii')można po prostu wyrazić jako b'Hello world'.

generator_stop

Zastępuje StopIterationwyjątek zastosowany w funkcjach generatora RuntimeError.

Innym niewymienionym powyżej zastosowaniem jest to, że __future__instrukcja wymaga również użycia interpreterów języka Python 2.1+, ponieważ użycie starszej wersji spowoduje zgłoszenie wyjątku czasu wykonywania.


Bibliografia

Robert Grossman
źródło
Zakładając, że jesteś offline, skąd Python wie, czy przyszła wersja jest dostępna, czy nie? I w jaki sposób korzysta z przyszłych funkcji, jeśli na komputerze nie zainstalowano przyszłej wersji Pythona?
Mohsen Haddadi
25

A może to tak, jakby powiedzieć „Ponieważ jest to python v2.7, użyj innej funkcji„ print ”, która została również dodana do python v2.7, po tym jak została dodana w python 3. Zatem moje„ print ”nie będzie już instrukcjami (np. print „wiadomość”), ale funkcje (np. print („wiadomość”, opcje)). W ten sposób, gdy mój kod jest uruchamiany w Pythonie 3, „print” nie ulegnie uszkodzeniu. ”

W

from __future__ import print_function

print_function to moduł zawierający nową implementację 'print', zgodnie z tym, jak zachowuje się w Pythonie v3.

To ma więcej wyjaśnień: http://python3porting.com/noconv.html

Praym
źródło
2

Jednym z zastosowań, które uznałem za bardzo przydatne, jest moduł print_functionfrom __future__.

W Pythonie 2.7 chciałem, aby znaki z różnych instrukcji print były drukowane w tym samym wierszu bez spacji.

Można to zrobić za pomocą przecinka („,”) na końcu, ale dodaje on również dodatkowe miejsce. Powyższe stwierdzenie używane jako:

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

Spowoduje to wydrukowanie wartości v_numz każdej iteracji w jednym wierszu bez spacji.

Abhi31jeet
źródło
-4

Począwszy od Python 3.0, print nie jest już tylko instrukcją, lecz funkcją. i jest uwzględniony w PEP 3105.

Myślę też, że pakiet Python 3.0 nadal ma te specjalne funkcje. Zobaczmy jego użyteczność poprzez tradycyjny „program Pyramid” w Pythonie:

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:
*
**
***
****

Jeśli użyjemy normalnej funkcji drukowania, nie będziemy w stanie osiągnąć tego samego wyniku, ponieważ print () ma dodatkową linię nowego wiersza. Dlatego za każdym razem, gdy wykonywana jest wewnętrzna pętla for, drukuje * w następnym wierszu.

Vikash Gupta
źródło