__Future__ trong Python được sử dụng để làm gì và sử dụng khi nào và khi nào nó hoạt động


693

__future__thường xuyên xuất hiện trong các mô-đun Python. Tôi không hiểu dùng để làm gì __future__và làm thế nào / khi nào sử dụng nó ngay cả sau khi đọc tài liệu của Python__future__ .

Bất cứ ai có thể giải thích với các ví dụ?

Một vài câu trả lời liên quan đến việc sử dụng cơ bản của __future__ tôi đã nhận được có vẻ đúng.

Tuy nhiên, tôi cần hiểu thêm một điều nữa về cách thức __future__ hoạt động:

Khái niệm khó hiểu nhất đối với tôi là cách phát hành python hiện tại bao gồm các tính năng cho các bản phát hành trong tương lai và cách chương trình sử dụng tính năng từ bản phát hành trong tương lai có thể được biên dịch thành công trong phiên bản Python hiện tại.

Tôi đoán rằng bản phát hành hiện tại được đóng gói với các tính năng tiềm năng cho tương lai. Tuy nhiên, các tính năng chỉ khả dụng khi sử dụng __future__vì chúng không phải là tiêu chuẩn hiện tại. Hãy cho tôi biết nếu tôi đúng.


10
Đây là đề xuất ban đầu cho tuyên bố trong tương lai. Tôi thấy nó hữu ích trong việc hiểu tại sao nó ở đó ngay từ đầu và vì thế khi nào và làm thế nào để sử dụng nó theo cách tự nhiên. python.org/dev/peps/pep-0236
Jpaji Rajquer


3
Một tuyên bố trong tương lai là một chỉ thị cho trình biên dịch rằng một mô-đun cụ thể sẽ được biên dịch bằng cú pháp hoặc ngữ nghĩa sẽ có sẵn trong một bản phát hành Python được chỉ định trong tương lai. Tuyên bố trong tương lai nhằm giảm bớt sự di chuyển sang các phiên bản Python trong tương lai giới thiệu các thay đổi không tương thích với ngôn ngữ. Nó cho phép sử dụng các tính năng mới trên cơ sở từng mô-đun trước khi phát hành tính năng này trở thành tiêu chuẩn.
shivam13juna

Câu trả lời:


384

Với __future__sự bao gồm của mô-đun, bạn có thể dần dần quen với các thay đổi không tương thích hoặc với những thay đổi như vậy giới thiệu các từ khóa mới.

Ví dụ, để sử dụng trình quản lý ngữ cảnh, bạn phải thực hiện from __future__ import with_statementtrong 2.5, vì withtừ khóa là mới và không nên được sử dụng làm tên biến nữa. Để sử dụng withlàm từ khóa Python trong Python 2.5 trở lên, bạn sẽ cần sử dụng nhập từ trên.

Một ví dụ khác là

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

Không có __future__nội dung, cả hai printcâu lệnh sẽ in1 .

Sự khác biệt bên trong là không có nhập đó, /được ánh xạ tới __div__()phương thức, trong khi với nó, __truediv__()được sử dụng. (Trong mọi trường hợp, //các cuộc gọi __floordiv__().)

Apropose print: printtrở thành một hàm trong 3.x, mất thuộc tính đặc biệt của nó làm từ khóa. Vì vậy, nó là cách khác.

>>> print

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

151
đừng quên from __future__ import braces: p
mdeous

13
@zoogleflatt Nếu bạn là một người thích tab, bạn không biết PEP 8. Bạn không nên sử dụng các tab ...
glglgl 3/03/2015

5
@glglgl Về mặt kỹ thuật, nó chỉ nói rằng chúng được ưa thích. Nó hoàn toàn không rõ ràng với tôi sau khi đọc lý do tại sao điều này là chính xác, tôi đoán nó có các mức thụt lề khớp chính xác để làm cho mã gọn hơn?
Jpaji Rajquer 6/03/2015

4
@zoogleflatt Điều chắc chắn cũng xảy ra với thực tế là hầu hết mọi người sử dụng 4 khoảng trắng cho 1 mức độ thụt lề, vì lý do tương thích, một tab tương đương với 8 khoảng trắng và các tab và khoảng trắng không được khuyến khích (resp., AFAIK, thậm chí không được phép Py3)
glglgl 6/03/2015

1
@whiteSkar Hiện tại tôi chưa cập nhật các phiên bản mới hơn của python 3, nhưng tôi cho rằng nó vẫn đang được sử dụng, chỉ là bạn có thể không cần nó với các tính năng khá cũ này. Trong Python 3, printchắc chắn là một hàm, nhưng có thể có các tính năng khác có thể sử dụng __future__. : (Sửa thấy docs.python.org/3/library/__future__.html nơi nó vẫn được sử dụng.)
glglgl

195

Khi bạn làm

from __future__ import whatever

Bạn không thực sự sử dụng một importtuyên bố, mà là một tuyên bố trong tương lai . Bạn đang đọc tài liệu sai, vì bạn không thực sự nhập mô-đun đó.

Các câu lệnh trong tương lai là đặc biệt - chúng thay đổi cách mô-đun Python của bạn được phân tích cú pháp, đó là lý do tại sao chúng phải ở đầu tệp. Chúng mang ý nghĩa mới - hoặc khác biệt - cho các từ hoặc ký hiệu trong tệp của bạn. Từ các tài liệu:

Một tuyên bố trong tương lai là một chỉ thị cho trình biên dịch rằng một mô-đun cụ thể sẽ được biên dịch bằng cú pháp hoặc ngữ nghĩa sẽ có sẵn trong một bản phát hành Python được chỉ định trong tương lai. Tuyên bố trong tương lai nhằm giảm bớt sự di chuyển sang các phiên bản Python trong tương lai giới thiệu các thay đổi không tương thích với ngôn ngữ. Nó cho phép sử dụng các tính năng mới trên cơ sở từng mô-đun trước khi phát hành tính năng này trở thành tiêu chuẩn.

Nếu bạn thực sự muốn nhập __future__mô-đun, chỉ cần làm

import __future__

và sau đó truy cập nó như bình thường.


4
Về mặt kỹ thuật, nó cũng là một câu lệnh nhập khẩu, vì tên liên quan được liên kết với một biến cục bộ. from __future__ import print_functioncả hai đều thay đổi hành vi của printtừ khóa và có thời gian chạy ảnh hưởng tương đương vớiprint_function = __import__("__future__").print_function
pppery

112

__future__ là một mô-đun giả mà các lập trình viên có thể sử dụng để kích hoạt các tính năng ngôn ngữ mới không tương thích với trình thông dịch hiện tại . Ví dụ, biểu thức 11/4hiện đang đánh giá 2. Nếu mô-đun mà nó được thực thi đã kích hoạt phân chia thực sự bằng cách thực thi:

from __future__ import division

các biểu thức 11/4sẽ đánh giá để 2.75. Bằng cách nhập __future__mô-đun và đánh giá các biến của nó, bạn có thể biết khi nào một tính năng mới lần đầu tiên được thêm vào ngôn ngữ và khi nào nó sẽ trở thành mặc định:

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

1
Vì vậy, dựa trên phiên bản phát hành trong các biến, nếu trình thông dịch của bạn đang sử dụng phiên bản muộn hơn chỉ định, thì đó import __future__ xyzcó phải là phiên bản không?
Ray

4
Nó hơi giống với một polyfill trong thế giới trình duyệt
cs01

47

Nó có thể được sử dụng để sử dụng các tính năng sẽ xuất hiện trong các phiên bản mới hơn trong khi có bản phát hành Python cũ hơn.

Ví dụ

>>> from __future__ import print_function

sẽ cho phép bạn sử dụng printnhư một chức năng:

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

29

Đã có một số câu trả lời tuyệt vời, nhưng không ai trong số họ giải quyết một danh sách đầy đủ về những gì __future__tuyên bố hiện đang hỗ trợ.

Một cách đơn giản, các __future__tuyên bố buộc thông dịch Python để sử dụng các tính năng mới của ngôn ngữ.


Các tính năng mà nó hiện đang hỗ trợ là như sau:

nested_scopes

Trước Python 2.1, đoạn mã sau sẽ đưa ra NameError :

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

Lệnh from __future__ import nested_scopesnày sẽ cho phép tính năng này được kích hoạt.

generators

Các hàm tạo được giới thiệu như hàm dưới đây để lưu trạng thái giữa các lệnh gọi hàm liên tiếp:

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

division

Phân chia cổ điển được sử dụng trong các phiên bản Python 2.x. Có nghĩa là một số tuyên bố phân chia trả về một xấp xỉ hợp lý của phân chia ("phân chia thực sự") và các báo cáo khác trả lại sàn ("phân chia sàn"). Bắt đầu trong Python 3.0, phân chia thực được chỉ định bởi x/y, trong khi phân chia sàn được chỉ định bởi x//y.

Lệnh from __future__ import divisionnày buộc sử dụng phân chia kiểu Python 3.0.

absolute_import

Cho phép dấu ngoặc đơn để đính kèm nhiều importcâu lệnh. Ví dụ:

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

Thay vì:

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

Hoặc là:

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

with_statement

Thêm câu lệnh withdưới dạng từ khóa trong Python để loại bỏ sự cần thiết của try/finallycâu lệnh. Việc sử dụng phổ biến này là khi thực hiện I / O tập tin, chẳng hạn như:

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

print_function:

Buộc sử dụng print()lệnh gọi hàm kiểu ngoặc đơn Python 3 thay vì print MESSAGEcâu lệnh kiểu.

unicode_literals

Giới thiệu cú pháp bằng chữ cho bytesđối tượng. Có nghĩa là các tuyên bố nhưbytes('Hello world', 'ascii') có thể được biểu diễn đơn giản là b'Hello world'.

generator_stop

Thay thế việc sử dụng StopIteration ngoại lệ được sử dụng bên trong các hàm tạo RuntimeError.

Một công dụng khác không được đề cập ở trên là __future__ câu lệnh cũng yêu cầu sử dụng trình thông dịch Python 2.1+ vì sử dụng phiên bản cũ hơn sẽ ném ngoại lệ thời gian chạy.


Người giới thiệu


Giả sử bạn đang ngoại tuyến, làm thế nào python biết liệu phiên bản tương lai có sẵn hay không? Và làm thế nào để nó sử dụng các tính năng trong tương lai nếu bạn chưa cài đặt phiên bản python trong tương lai trên máy tính của mình?
Mohsen Haddadi

25

Hoặc giống như nói "Vì đây là python v2.7, hãy sử dụng chức năng 'in' khác nhau cũng đã được thêm vào python v2.7, sau khi nó được thêm vào python 3. Vì vậy, 'print' của tôi sẽ không còn là câu lệnh nữa (ví dụ: in "tin nhắn") nhưng các chức năng (ví dụ: in ("tin nhắn", tùy chọn). Bằng cách đó khi mã của tôi được chạy trong python 3, 'print' sẽ không bị hỏng. "

Trong

from __future__ import print_function

print_function là mô-đun chứa cách triển khai 'print' mới theo cách nó hoạt động trong python v3.

Điều này có thêm lời giải thích: http://python3porting.com/noconv.html


2

Một trong những cách sử dụng mà tôi thấy rất hữu ích là print_functiontừ __future__mô-đun.

Trong Python 2.7, tôi muốn các ký tự từ các câu lệnh in khác nhau được in trên cùng một dòng mà không có khoảng trắng.

Nó có thể được thực hiện bằng cách sử dụng dấu phẩy (",") ở cuối, nhưng nó cũng nối thêm một khoảng trắng. Câu lệnh trên khi được sử dụng như:

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

Điều này sẽ in giá trị v_numtừ mỗi lần lặp trong một dòng không có khoảng trắng.


-3

Sau Python 3.0 trở đi, in không còn chỉ là một câu lệnh, thay vào đó là một chức năng. và được bao gồm trong PEP 3105.

Ngoài ra tôi nghĩ gói Python 3.0 vẫn có các chức năng đặc biệt này. Hãy xem khả năng sử dụng của nó thông qua "chương trình Kim tự tháp" truyền thống trong 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:
*
**
***
****

Nếu chúng tôi sử dụng chức năng in bình thường, chúng tôi sẽ không thể đạt được cùng một đầu ra, vì print () đi kèm với một dòng mới. Vì vậy, mỗi khi vòng lặp bên trong thực thi, nó sẽ in * lên dòng tiếp theo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.