Подтвердить что ты не робот

Может ли от __future__ импортировать... гарантировать совместимость Python 2 и 3?

Мне не интересно разогревать "Python 2 или Python 3?" (хотя самый последний из них, который я нашел, старше одного года), но я наткнулся на это выражение:

Вы можете написать код Python 3 под Python 2, если ваш файл начинается с линией:

from __future__ import absolute_import, division, generators, unicode_literals, print_function, nested_scopes, with_statement

С этой строкой ваш код будет работать с Python 2 или Python 3. Там могут быть редкие случаи, когда он не работает, но у меня есть не найден,

Это правда? Является ли эта единственная строка достаточной для того, чтобы код, который вы пишете, выполнялся как на Python 2.x( >= 2.5, я предполагаю), так и на 3.x(если предполагается, что импортированные модули доступны в обоих)?

4b9b3361

Ответ 1

"Это зависит от

Нет: Добавление этих импортных данных в код Python 2 не приведет к запуску под Python 3.

Да:. При наличии этих данных вы можете писать код, который работает как под Python 2, так и с Python 3.

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

Итак, в заключение, эти импорты - это немного красная селедка, и утверждение более ошибочно, чем право.

Однако, что не означает, что писать код, который работает как под Python 2, так и с Python 3, невозможно или даже обязательно очень сложно. Подробнее см. http://python3porting.com/.

Ответ 2

Я бы сказал, что нет, это балони. Даже при импорте все еще существуют существенные различия между Python 2 и 3: например, input() в Python 3 похож на raw_input() в Python 2; range() в Python 3 похож на xrange() на Python 2. В случае xrange() вам, вероятно, удастся избежать использования range() в Python 2, если диапазоны невелики, но если они большие, ваша программа может иметь очень различное использование памяти в Python 2 и Python 3.

В код можно добавить что-то вроде этого:

try:
    range = xrange
    input = raw_input
except NameError:
    pass

Но тогда вам нужно найти все эти крайние случаи и исправить их. Например, существуют методы keys() и values() dict, которые возвращают итераторы в Python 3, но списки в Python 2, поэтому вам нужно написать подкласс dict, который "исправляет" это (и затем никогда не используйте словарные литералы в своем коде, не обертывая их, поскольку в противном случае они имели бы встроенный тип dict).

Я полагаю, что, используя __future__ и различные исправления, и ограничивая себя написанием кода в подмножестве Python, созданного таким образом, который будет работать под 2.x и 3.x, возможно, напишите код, который выполняется в обеих версиях. Похоже, что много работы. Там есть причина, когда утилита 2to3...

Ответ 3

Это не невозможно, в зависимости от требований вашей кодовой базы. Вероятно, вы найдете библиотеку six (2 * 3, ха-ха); другим полезным инструментом является python-modernize, который пытается преобразовать ваш код в состояние кросс-совместимости.

Ответ 4

Это сделает его более вероятным, но есть некоторые вещи, которые не могут быть получены из импорта __future__, и некоторые вещи, которые удаляются в 3.x.

Сверху моей головы вы все равно можете использовать распаковку параметров tuple, которая удаляется в 3.x, и вы не сможете использовать красивую распаковку со звездообразным оператором, который вводится в 3.x.

например:

def some_function((x, y), magnitude): #This has been removed in 3.x
    pass

x, *y = (1, 2, 3) #This does not exist in 2.x

Тем не менее, с некоторой осторожностью, чтобы избежать таких вещей, вы можете определенно написать код, который работает в обеих версиях, да.

Очевидно, что это относится только к версиям 2.x, в которых есть встроенные в них функции. Из-за этого некоторые из этой строки на самом деле совершенно бессмысленны - например, нет причин для импорта generators, поскольку любая версия, которая может импортировать оператор with, уже будет иметь генераторы, работающие как стандартные. То же самое касается nested_scopes.

В общем, я рекомендую просто писать для 3.x - нет никаких препятствий для установки обеих версий обеих версий. Если вам действительно нужна поддержка 2.x, напишите для 2.x столько функций, сколько вы хотите, и используйте 2to3 для очистки всего остального.

Ответ 5

Нах. Другие отметили некоторую разницу, есть и другие. Один из самых фундаментальных заключается в том, что родные строки Python 3 являются многобайтными - это вызывает проблемы при общении с однобайтовыми механизмами, такими как каналы для других процессов. Другие включают переименование модулей (Tkinter to tkinter), True и False - теперь ключевые слова.

Даже сравнение может быть не таким, следующий неправильный код:

num = 42
txt = "3"

if txt < num:
    print ('Wow!')
else:
    print ('Doh!')

создает a TypeError на Py3, но не на Py2.

Распаковка была упомянута. методы словаря items(), keys() и values() объекты обратного просмотра (разные имена методов используются в версии 2.7). В итераторах Py3 используются больше, например, возвращаются из map() и filter() и т.д....

Ответ 6

Вы можете использовать будущий пакет: pip install future

In [1]: range(10)
Out[1]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: from future.builtins import range

In [3]: range(10)
Out[3]: range(0, 10)

Вот их чит-лист с большим количеством примеров: http://python-future.org/compatible_idioms.html