Для чего используется __future__ в Python и как / когда его использовать, и как он работает

694

__future__часто появляется в модулях Python. Я не понимаю , что __future__это и как / когда использовать его даже после прочтения питона __future__дока .

Кто-нибудь может объяснить примерами?

Несколько ответов относительно основного использования, которое __future__я получил, казалось правильным.

Тем не менее, мне нужно понять еще одну вещь относительно того, как __future__работает:

Наиболее запутанная концепция для меня заключается в том, как текущий выпуск Python включает в себя функции для будущих выпусков, и как программа, использующая функцию из будущего выпуска, может быть успешно скомпилирована в текущей версии Python.

Я предполагаю, что текущий выпуск упакован с потенциальными функциями на будущее. Однако функции доступны только при использовании, __future__поскольку они не соответствуют текущему стандарту. Дайте мне знать, если я прав.

Лесли
источник
10
Это оригинальное предложение для будущего заявления. Я обнаружил, что это полезно для понимания, почему он вообще существует, и поэтому, когда и как его использовать, следует естественным образом. python.org/dev/peps/pep-0236
Jpaji Rajnish
56
Это в основном эквивалент «я думаю, ты не готов к этому, но твоим детям это понравится» .
Жан-Франсуа Корбетт
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__материала оба printутверждения будут напечатаны 1.

Внутренняя разница заключается в том, что без этого импорта метод /сопоставляется __div__(), а вместе с ним __truediv__()используется. (В любом случае //звонит __floordiv__().)

Кстати print: printстановится функцией в 3.x, теряя свое специальное свойство в качестве ключевого слова. Так что все наоборот.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>
glglgl
источник
151
не забывайте from __future__ import braces: р
безумно
13
@zoogleflatt Если вы более любитель вкладок, вы не знаете PEP 8. Настоятельно рекомендуется не использовать вкладки ...
glglgl
5
@glglgl Ну, технически это просто говорит, что они предпочтительнее. После прочтения мне было не совсем понятно, почему это именно так, я полагаю, что уровни отступа должны точно совпадать, чтобы сделать код более аккуратным?
Jpaji Rajnish
4
@zoogleflatt Это, безусловно, также связано с тем фактом, что большинство людей используют 4 пробела для 1 уровня отступа, что по причинам совместимости одна вкладка эквивалентна 8 пробелам, а смешивание вкладок и пробелов не рекомендуется (соответственно, AFAIK, даже не разрешено в Py3)
glglgl
1
@whiteSkar В настоящее время я не в курсе новых версий Python 3, но я предполагаю, что он все еще используется, просто вам, вероятно, не нужны эти довольно старые функции. В Python 3 printэто определенно функция, но могут быть и другие функции, которые можно использовать __future__. (Изменить: см. Docs.python.org/3/library/__future__.html, где он все еще используется.)
glglgl
195

Когда вы делаете

from __future__ import whatever

На самом деле вы используете не importутверждение, а будущее заявление . Вы читаете не те документы, так как вы на самом деле не импортируете этот модуль.

Будущие операторы особенные - они изменяют способ анализа вашего модуля Python, поэтому они должны находиться в верхней части файла. Они дают новое - или другое - значение для слов или символов в вашем файле. Из документов:

Будущее утверждение - это директива для компилятора о том, что определенный модуль должен быть скомпилирован с использованием синтаксиса или семантики, которые будут доступны в указанном будущем выпуске Python. Будущее утверждение предназначено для облегчения перехода на будущие версии Python, которые вносят несовместимые изменения в язык. Это позволяет использовать новые функции для каждого модуля до выпуска, в котором эта функция становится стандартной.

Если вы действительно хотите импортировать __future__модуль, просто выполните

import __future__

а затем получить к нему доступ, как обычно.

AGF
источник
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)
CodeArtist
источник
1
Итак, в зависимости от версии релиза в переменных, если ваш интерпретатор использует более позднюю версию, чем указано, import __future__ xyzявляется ли запретным?
Рэй
4
Это несколько аналогично полифиллу в мире браузеров
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. Это означает, что некоторые операторы деления возвращают разумное приближение деления («истинное деление»), а другие возвращают слово («деление по полу»). Начиная с Python 3.0, истинное деление определяется как x/y, тогда как нижнее деление определяется как x//y.

В from __future__ import divisionдирективе прижимает использование Python 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утверждениях. Обычно это используется при выполнении файлового ввода-вывода, например:

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

print_function:

Принудительно использует print()вызов функции в стиле круглых скобок Python 3 вместо print MESSAGEвыражения стиля.

unicode_literals

Вводит буквальный синтаксис для bytesобъекта. Это означает, что такие заявления bytes('Hello world', 'ascii')могут быть просто выражены как b'Hello world'.

generator_stop

Заменяет использование StopIterationисключения, используемого внутри функций генератора, RuntimeErrorисключением.

Еще одно использование, не упомянутое выше, заключается в том, что для этого __future__утверждения также требуется использование интерпретаторов Python 2.1+, поскольку использование более старой версии вызовет исключение времени выполнения.


Ссылки

Роберт Гроссман
источник
Предполагая, что вы не в сети, как Python узнает, доступна ли будущая версия или нет? И как он использует будущие функции, если на вашем компьютере не установлена ​​будущая версия python?
Мохсен Хаддади
25

Или это как сказать «Поскольку это Python v2.7, используйте эту другую функцию« печать », которая также была добавлена ​​в Python v2.7, после того, как она была добавлена ​​в Python 3. Поэтому мой« печать »больше не будет операторами (например, print «message»), но функции (например, print («message», options)). Таким образом, когда мой код запускается в python 3, «print» не сломается ».

В

from __future__ import print_function

print_function - это модуль, содержащий новую реализацию print в соответствии с его поведением в python v3.

Это имеет больше объяснения: http://python3porting.com/noconv.html

Praym
источник
2

Одним из применений, которое я считаю очень полезным, является модуль print_functionfrom __future__.

В Python 2.7 я хотел, чтобы символы из разных операторов print печатались в одной строке без пробелов.

Это может быть сделано с помощью запятой (",") в конце, но это также добавляет дополнительный пробел. Вышеприведенное утверждение при использовании в качестве:

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

Это выведет значение v_numкаждой итерации в одну строку без пробелов.

Abhi31jeet
источник
-4

Начиная с Python 3.0, print больше не просто оператор, а функция. и включен в PEP 3105.

Также я думаю, что пакет Python 3.0 все еще обладает этими специальными функциями. Давайте посмотрим на его удобство использования через традиционную «программу Pyramid» на 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:
*
**
***
****

Если мы используем обычную функцию печати, мы не сможем добиться того же результата, так как print () поставляется с дополнительной новой строкой. Поэтому каждый раз, когда выполняется внутренний цикл for, он будет печатать * на следующей строке.

Викаш Гупта
источник