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

Как написать Python 2.x как можно более совместимым с Python 3.x?

Существует много способов включить функции Python 3.x в Python 2.x, поэтому код скриптов Python 2.x может быть легко преобразован в Python 3.x в будущем. Один из этих примеров заменяет оператор print функцией print():

>>> from __future__ import print_function

Есть ли список или ресурс, который может дать некоторые идеи о том, как сделать код Python 2.x максимально приближенным к Python 3.x?

Не могли бы вы привести примеры других полезных импорта или определений, которые могут сделать Python 2.x более похожим на Python 3.x?

Предположим, что у нас есть последний Python 2.x(2.7.2 на данный момент, я считаю) в нашем распоряжении.

4b9b3361

Ответ 1

Я делаю последние штрихи примерно на 5000 строк, дедуплицируя программу резервного копирования (http://stromberg.dnsalias.org/~strombrg/backshift/), которая выполняется на CPython 2. [ 567], CPython 3. [00123] (3.3 все еще альфа 0), Pypy 1.7 и Jython trunk. Я также пробовал IronPython, но это было совсем другое: в нем не было стандартной библиотеки, поэтому никакой обратной перестройки не было. О, и он может использовать Cython для своей самой внутренней петли, или psyco, но pypy быстрее, чем любой, особенно на 32-битных системах.

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

1) print (variable) работает одинаково как на 2.x, так и на 3.x. print (variable1, variable2) нет. В 2.x print (variable) говорит: "Оцените это выражение в скобках и распечатайте единственный результат, используя оператор печати". В версии 3.x print (variable) говорит: "Вызовите функцию печати для этого единственного результата, поэтому print ('abc% d% d'% (1, 2)) отлично работает в обоих случаях, поскольку это однозначный результат, и оба grok используют оператор% для форматирования строк.

2) Избегайте восьмеричных констант. Вместо записи 0755 напишите (7 * 64 + 5 * 8 + 5).

3) Для выполнения двоичного ввода-вывода я использовал мой модуль bufsock. http://stromberg.dnsalias.org/~strombrg/bufsock.html Я бы os.open файл и обернул его с помощью bufsock (или использовал класс rawio в модуле). В 2.x это вернет строку байтов, закодированную как 8-битные символьные строки. В 3.x это вернет объект байтов, который действует как список небольших целых чисел. Затем я просто обошел один или другой, тестируя "isinstance (foo, str)", как необходимо, чтобы различать эти два. Я сделал это, потому что в резервной программе байты - это байты - я не хотел возиться с кодировками, защищающими данные, надежно, а не все кодировки в оба конца.

4) При выполнении исключений избегайте ключевого слова "как". Вместо этого используйте EG:

  try:
     self.update_timestamp()
  except (OSError, IOError):
     dummy, utime_extra, dummy = sys.exc_info()
     if utime_extra.errno == errno.ENOENT:

5) Связка модулей была переименована при переходе от 2.x до 3.x. Поэтому попробуйте импортировать один из них в пустой модуль, с чем-то вроде:

try:
   from anydbm import *
except ImportError:
   from dbm import *

... это будет отображаться в модуле отдельно, с именем EG adbm.py. Тогда в любое время, когда мне понадобилось хранилище для ключей, я бы импортировал adbm вместо двух разных вещей, необходимых для 2.x или 3.x напрямую. Тогда я бы pylint все, но этот прочный модуль, adbm.py - и тому подобное, что pylint не понравилось. Идея заключалась в том, чтобы собрать все возможное, исключая правило "все, что нужно", в крошечном модуле само по себе, одно исключение для каждого модуля.

6) Это помогает много настроить автоматические модульные тесты и системные тесты, которые выполняются на 2.x и 3.x, а затем часто тестировать по крайней мере один переводчик 2.x, а также, по крайней мере, один 3.x переводчик. Я также часто запускаю pylint против моего кода, хотя и только pylint, который проверял соответствие 2.5.x - я начал проект до того, как pylint получил поддержку 3.x.

7) Я установил небольшой модуль "python2x3", который имеет несколько констант и вызывающих элементов, чтобы облегчить жизнь: http://stromberg.dnsalias.org/svn/python2x3/trunk/python2x3.py p >

8) b '' литералы не работают в 2.5, хотя они работают в 2. [67]. Вместо того, чтобы пытаться препроцесс или что-то еще, я создал константу_mod.py, в которой было много вещей, которые обычно были бы b''-литералами в 3.x и преобразовывали их из простой строки в любой тип "байтов" для 2.x или 3.x. Поэтому они конвертируются один раз при импорте модуля, но не во время выполнения. Если вы нацеливаетесь на 2. [67] и, возможно, лучший способ, но когда я начал проект Pypy, он был совместим только с 2.5, а Jython все еще есть.

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

10) Это помогает LOT иметь кучу интерпретаторов python для тестирования. Я построил 2. [567] и 3. [ и спрятал их в/usr/local/cpython-x.y/для легкого тестирования. Я также поставил некоторые Pypy и Jython в /usr/local, снова для легкого тестирования. Наличие script для автоматизации сборки CPython было весьма ценным.

Я считаю, что это были все искажения, которые мне нужны для получения высоконагруженной базы данных python в нетривиальном проекте. Одно большое упущение в списке, который я написал выше, заключается в том, что я не пытаюсь использовать объекты unicode - что-то, что кто-то еще, вероятно, лучше квалифицирует для комментариев.

НТН

Ответ 2

Вы должны проверить Портирование кода на Python до 3.0. Хотя он направлен на портирование, он отвечает по существу тем же самым вопросом; вы просто не пройдете весь путь.

Ответ 3

Существует целая глава об этом в разделе Портирование на Python 3 ". Также не пропустите приложения, которые перечисляют языковые различия с обходными способами для поддержки обоих языков.

Вероятно, вы захотите использовать шесть библиотек, хотя это возможно сделать без него.

Ответ 5

У меня это в верхней части моего шаблона Python 2.7 script:

from __future__ import division, print_function
from future_builtins import ascii, filter, hex, map, oct, zip

Ответ 6

Поскольку он еще не упоминался: я нашел этот чит-лист действительно полезным для этой конкретной цели.