__future__ คืออะไรใน Python ที่ใช้และวิธีการใช้งานเมื่อไรและมันทำงานอย่างไร


694

__future__มักปรากฏในโมดูล Python ฉันไม่เข้าใจสิ่งที่__future__เป็นและวิธีการ / เมื่อจะใช้งานได้แม้กระทั่งหลังจากที่ได้อ่านหลามของ__future__เอกสาร

มีใครอธิบายได้บ้างไหม?

คำตอบเล็ก ๆ น้อย ๆ เกี่ยวกับการใช้งานพื้นฐานที่__future__ฉันได้รับนั้นถูกต้อง

อย่างไรก็ตามฉันต้องเข้าใจอีกสิ่งหนึ่งเกี่ยวกับวิธีการ__future__ทำงาน:

แนวคิดที่สับสนมากที่สุดสำหรับฉันคือวิธีที่ไพ ธ อนรีลีสปัจจุบันมีคุณสมบัติสำหรับรีลีสในอนาคตและวิธีการที่โปรแกรมที่ใช้ฟีเจอร์จากรีลีสในอนาคตสามารถรวบรวมได้สำเร็จใน Python เวอร์ชันปัจจุบัน

ฉันเดาว่ารุ่นปัจจุบันบรรจุด้วยคุณสมบัติที่เป็นไปได้สำหรับอนาคต อย่างไรก็ตามคุณสมบัตินี้มีให้ใช้งานโดยใช้เพียงอย่างเดียว__future__เพราะไม่ใช่มาตรฐานปัจจุบัน แจ้งให้เราทราบหากฉันถูก


10
นี่คือข้อเสนอดั้งเดิมสำหรับคำสั่งในอนาคต ฉันพบว่ามันมีประโยชน์ในการทำความเข้าใจว่าทำไมมันมีอยู่ในสถานที่แรกและดังนั้นเมื่อใดและอย่างไรที่จะใช้มันเป็นไปตามธรรมชาติ python.org/dev/peps/pep-0236
Jpaji Rajnish

55
มันเป็นพื้นเทียบเท่า"ผมคิดว่าคุณยังไม่พร้อมสำหรับเรื่องนี้ แต่เด็กของคุณจะรักมัน"
Jean-François Corbett

3
คำสั่งในอนาคตเป็นคำสั่งให้คอมไพเลอร์ที่โมดูลเฉพาะควรจะรวบรวมโดยใช้ไวยากรณ์หรือความหมายที่จะสามารถใช้ได้ใน Python รุ่นอนาคตที่ระบุ ข้อความสั่งในอนาคตมีจุดประสงค์เพื่อลดความยุ่งยากในการโยกย้ายไปสู่ ​​Python เวอร์ชันอนาคตที่แนะนำการเปลี่ยนแปลงภาษาที่เข้ากันไม่ได้ อนุญาตให้ใช้คุณลักษณะใหม่แบบต่อโมดูลก่อนที่จะเผยแพร่คุณสมบัติที่เป็นมาตรฐาน
shivam13juna

คำตอบ:


384

ด้วย__future__การรวมโมดูลคุณจะค่อยๆคุ้นเคยกับการเปลี่ยนแปลงที่เข้ากันไม่ได้หรือกับคำแนะนำใหม่ ๆ

ตัวอย่างเช่นสำหรับการใช้ตัวจัดการบริบทคุณต้องทำfrom __future__ import with_statementใน 2.5 เนื่องจากwithคำหลักใหม่และไม่ควรใช้เป็นชื่อตัวแปรอีกต่อไป ในการใช้withเป็นคำหลัก Python ใน Python 2.5 หรือเก่ากว่าคุณจะต้องใช้การนำเข้าจากด้านบน

อีกตัวอย่างหนึ่งคือ

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

โดยไม่ต้อง__future__สิ่งที่ทั้งสองงบจะพิมพ์print1

ความแตกต่างภายในคือการที่ไม่มีการนำเข้านั้น/จะถูกแมปกับ__div__()วิธีการขณะที่__truediv__()ใช้มัน (ไม่ว่าในกรณีใด//โทร__floordiv__())

Apropos print: printกลายเป็นฟังก์ชันใน 3.x สูญเสียคุณสมบัติพิเศษของมันเป็นคำหลัก ดังนั้นมันจึงเป็นอีกทางหนึ่ง

>>> print

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

151
อย่าลืมfrom __future__ import braces: p
mdeous

13
@zoogleflatt ถ้าคุณเป็นคนที่แต่งตัวประหลาดมากกว่าแท็บคุณไม่รู้จัก PEP 8 ขอแนะนำอย่างยิ่งที่จะไม่ใช้แท็บ ...
glglgl

5
@glglgl ในทางเทคนิคแล้วมันแค่บอกว่าพวกเขาต้องการ มันไม่ชัดเจนเลยสำหรับฉันหลังจากที่ได้อ่านว่าทำไมมันถึงเป็นแบบนี้ฉันเดาว่ามันจะมีระดับเยื้องตรงกับการสร้างรหัส neater?
Jpaji Rajnish

4
@zoogleflatt แน่นอนว่ามันเกี่ยวข้องกับความจริงที่ว่าคนส่วนใหญ่ใช้ 4 ช่องว่างสำหรับ 1 ระดับของการเยื้องซึ่งสำหรับเหตุผลที่เข้ากันได้หนึ่งแท็บเทียบเท่ากับ 8 ช่องว่างและแท็บผสมและช่องว่างนั้นไม่สนับสนุน (เช่น AFAIK แม้ไม่อนุญาต Py3)
glglgl

1
@whiteSkar ฉันยังไม่ทันสมัยกับ python 3 รุ่นใหม่ แต่ฉันคิดว่ามันยังใช้งานอยู่แค่ว่าคุณไม่จำเป็นต้องใช้มันด้วยคุณสมบัติเก่า ๆ เหล่านี้ ในหลาม 3 printแน่นอนฟังก์ชั่น แต่อาจจะมีคุณสมบัติอื่น ๆ __future__ที่อาจจะใช้ (แก้ไข: ดูdocs.python.org/3/library/__future__.htmlที่ยังใช้อยู่)
glglgl

195

เมื่อคุณทำ

from __future__ import whatever

คุณไม่ได้จริงโดยใช้importคำสั่ง แต่คำสั่งในอนาคต คุณกำลังอ่านเอกสารที่ไม่ถูกต้องเนื่องจากคุณไม่ได้นำเข้าโมดูลนั้น

ข้อความสั่งในอนาคตเป็นสิ่งพิเศษ - พวกเขาเปลี่ยนวิธีการแยกวิเคราะห์โมดูลของ Python ของคุณซึ่งเป็นสาเหตุที่ต้องอยู่ด้านบนของไฟล์ พวกเขาให้ใหม่ - หรือแตกต่าง - ความหมายกับคำหรือสัญลักษณ์ในไฟล์ของคุณ จากเอกสาร:

คำสั่งในอนาคตเป็นคำสั่งให้คอมไพเลอร์ที่โมดูลเฉพาะควรจะรวบรวมโดยใช้ไวยากรณ์หรือความหมายที่จะสามารถใช้ได้ใน Python รุ่นอนาคตที่ระบุ ข้อความสั่งในอนาคตมีจุดประสงค์เพื่อลดความยุ่งยากในการโยกย้ายไปสู่ ​​Python เวอร์ชันอนาคตที่แนะนำการเปลี่ยนแปลงภาษาที่เข้ากันไม่ได้ อนุญาตให้ใช้คุณลักษณะใหม่แบบต่อโมดูลก่อนที่จะเผยแพร่คุณสมบัติที่เป็นมาตรฐาน

หากคุณต้องการนำเข้า__future__โมดูลจริงเพียงแค่ทำ

import __future__

จากนั้นเข้าถึงได้ตามปกติ


4
ในทางเทคนิคมันยังเป็นคำสั่งนำเข้าเนื่องจากชื่อที่เกี่ยวข้องถูกผูกไว้กับตัวแปรท้องถิ่น from __future__ import print_functionทั้งเปลี่ยนพฤติกรรมของprintคำหลักและมีผลต่อรันไทม์เทียบเท่ากับprint_function = __import__("__future__").print_function
pppery

112

__future__ เป็นโมดูลหลอกซึ่งโปรแกรมเมอร์สามารถใช้เพื่อเปิดใช้งานคุณสมบัติภาษาใหม่ซึ่งไม่สามารถใช้งานร่วมกับล่ามปัจจุบันได้ ยกตัวอย่างเช่นการแสดงออกในขณะนี้ประเมิน11/4 2หากโมดูลที่ถูกเรียกใช้งานได้เปิดใช้งานการหารจริงโดยการดำเนินการ:

from __future__ import division

การแสดงออกจะประเมิน11/4 2.75โดยการนำเข้า__future__โมดูลและการประเมินตัวแปรคุณสามารถดูได้ว่าเมื่อใดที่คุณสมบัติใหม่จะถูกเพิ่มเข้าไปในภาษาและเมื่อมันจะกลายเป็นค่าเริ่มต้น:

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

1
ดังนั้นตามรุ่นที่วางจำหน่ายในตัวแปรหากล่ามของคุณใช้รุ่นที่ใหม่กว่าที่ระบุไว้import __future__ xyzนั่นคือ no-op?
เรย์

4
มันค่อนข้างคล้ายกับ polyfill ในโลกของเบราว์เซอร์
cs01

47

มันสามารถใช้ในการใช้คุณสมบัติที่จะปรากฏในรุ่นที่ใหม่กว่าในขณะที่มี Python รุ่นเก่ากว่า

ตัวอย่างเช่น

>>> from __future__ import print_function

จะอนุญาตให้คุณใช้printเป็นฟังก์ชั่น:

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

29

มีคำตอบที่ยอดเยี่ยมอยู่แล้ว แต่ก็ไม่มีคำตอบใดที่แสดงรายการที่สมบูรณ์ของ__future__คำสั่งในปัจจุบัน

กล่าวง่ายๆคือการ__future__บังคับให้ล่าม Python ใช้คุณสมบัติใหม่ของภาษา


คุณสมบัติที่รองรับในปัจจุบันมีดังต่อไปนี้:

nested_scopes

ก่อนหน้า Python 2.1 รหัสต่อไปนี้จะเพิ่มNameError :

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

from __future__ import nested_scopesสั่งจะอนุญาตให้มีคุณลักษณะนี้เพื่อเปิดใช้งาน

generators

ฟังก์ชั่นเครื่องกำเนิดไฟฟ้าที่แนะนำเช่นด้านล่างเพื่อบันทึกสถานะระหว่างการเรียกใช้ฟังก์ชันต่อเนื่อง:

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

division

การแบ่งแบบคลาสสิกถูกใช้ในเวอร์ชัน Python 2.x หมายความว่าคำสั่งการหารบางรายการส่งคืนการประมาณแบบสมเหตุสมผลของการหาร ("การหารที่แท้จริง") และการอ้างถึงส่วนอื่น ๆ ส่งคืนพื้น ("การหารชั้น") เริ่มต้นในหลาม 3.0 ส่วนความจริงจะถูกระบุโดยในขณะที่ส่วนชั้นที่ระบุไว้โดยx/yx//y

from __future__ import divisionกองกำลังสั่งการใช้งานของงูหลามส่วน 3.0 สไตล์

absolute_import

อนุญาตให้วงเล็บล้อมหลายimportคำสั่ง ตัวอย่างเช่น:

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

แทน:

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

หรือ:

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

with_statement

เพิ่มคำสั่งwithเป็นคำหลักใน Python เพื่อลดความต้องการtry/finallyคำสั่ง การใช้งานทั่วไปของสิ่งนี้คือเมื่อทำไฟล์ I / O เช่น:

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

print_function:

บังคับให้ใช้print()การเรียกฟังก์ชันวงเล็บสไตล์ Python 3 แทนprint MESSAGEคำสั่ง style

unicode_literals

แนะนำไวยากรณ์ตัวอักษรสำหรับbytesวัตถุ ความหมายว่างบเช่นสามารถแสดงเป็นเพียงbytes('Hello world', 'ascii')b'Hello world'

generator_stop

แทนที่การใช้StopIterationข้อยกเว้นที่ใช้ภายในฟังก์ชันตัวสร้างด้วยRuntimeErrorข้อยกเว้น

การใช้งานอย่างอื่นที่ไม่ได้กล่าวถึงข้างต้นคือ__future__คำสั่งนั้นต้องการการใช้งาน Python 2.1+ ล่ามเนื่องจากการใช้รุ่นเก่าจะทำให้เกิดข้อยกเว้นรันไทม์


อ้างอิง


ถ้าคุณอยู่ในสถานะออฟไลน์แล้วไพ ธ อนจะรู้ได้อย่างไรว่าเวอร์ชั่นในอนาคตจะมีให้ใช้งานหรือไม่? และจะใช้คุณสมบัติต่าง ๆ ในอนาคตได้อย่างไรหากคุณยังไม่ได้ติดตั้งไพ ธ อนรุ่นอนาคตบนคอมพิวเตอร์ของคุณ?
Mohsen Haddadi

25

หรือมันเหมือนกับการพูดว่า "เนื่องจากนี่คือ python v2.7 ให้ใช้ฟังก์ชัน 'print' ที่แตกต่างกันซึ่งเพิ่มไปยัง python v2.7 หลังจากที่เพิ่มใน python 3 ดังนั้น 'print' ของฉันจะไม่เป็นคำสั่งอีกต่อไป (เช่นพิมพ์ "ข้อความ") แต่ฟังก์ชั่น (เช่นพิมพ์ ("ข้อความ" ตัวเลือก) วิธีการที่เมื่อรหัสของฉันทำงานในหลาม 3, 'พิมพ์' จะไม่แตกหัก "

ใน

from __future__ import print_function

print_function เป็นโมดูลที่มีการใช้งานใหม่ของ 'พิมพ์' ตามที่มันทำงานใน python v3

นี่มีคำอธิบายเพิ่มเติม: http://python3porting.com/noconv.html


2

หนึ่งในการใช้งานที่ฉันพบว่ามีประโยชน์มากคือprint_functionจาก__future__โมดูล

ใน Python 2.7 ฉันต้องการ chars จากคำสั่งการพิมพ์ที่แตกต่างกันที่จะพิมพ์ในบรรทัดเดียวกันโดยไม่มีช่องว่าง

มันสามารถทำได้โดยใช้เครื่องหมายจุลภาค (",") ในตอนท้าย แต่มันยังผนวกพื้นที่เพิ่มเติม ข้อความข้างต้นเมื่อใช้เป็น:

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

นี่จะพิมพ์ค่าของv_numการวนซ้ำแต่ละครั้งในบรรทัดเดียวโดยไม่มีช่องว่าง


-4

หลังจาก Python 3.0 ขึ้นไปการพิมพ์ไม่ได้เป็นเพียงแค่คำสั่ง แต่เป็นฟังก์ชั่นแทน และรวมอยู่ใน PEP 3105

ฉันคิดว่าแพ็คเกจ Python 3.0 ยังมีฟังก์ชั่นพิเศษเหล่านี้อยู่ ให้เห็นการใช้งานของมันผ่าน "โปรแกรมปิรามิด" แบบดั้งเดิมใน 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:
*
**
***
****

หากเราใช้ฟังก์ชั่นการพิมพ์ปกติเราจะไม่สามารถรับผลลัพธ์เดียวกันเนื่องจากการพิมพ์ () มาพร้อมกับบรรทัดใหม่พิเศษ ดังนั้นทุกครั้งที่ Inner สำหรับลูปรันมันจะพิมพ์ * ไปยังบรรทัดถัดไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.