Документация Python неофициальный перевод

pyporting.md

348 строк · 42.4 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.3/howto/pyporting.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Перенос кода с Python 2 на Python 389| автор: | Brett Cannon |10| --- | --- |1112Аннотация1314Поскольку Python 3 – это будущее Python, а Python 2 всё ещё активно используется, полезно иметь проект, доступный для обеих основных версий Python. Это руководство призвано помочь разобраться, как наилучшим образом поддерживать обе версии Python 2 и 3 одновременно.1516Если требуется портировать модуль расширения, а не чистый код Python, см. [*Портирование модулей расширения на Python 3*](https://python-all.ru/3.3/howto/cporting.html#cporting-howto).1718Если хотите узнать мнение одного из ключевых разработчиков Python о том, почему появился Python 3, прочитайте [Вопросы и ответы о Python 3](https://python-all.ru/3.3/howto/pyporting.html) от Ника Коглана.1920Если вы предпочитаете прочитать (бесплатную) книгу по переносу проекта на Python 3, обратите внимание на книгу [Porting to Python 3](https://python-all.ru/3.3/howto/pyporting.html) Леннарта Регебро; она охватывает большую часть материала, обсуждаемого в данном руководстве.2122Для помощи с портированием можно написать в список рассылки [python-porting](https://python-all.ru/3.3/howto/pyporting.html) с вопросами.2324## Краткая версия2526- Определите самую старую версию Python 2, которую планируется поддерживать (если таковая имеется)27- Убедитесь, что имеется тщательный набор тестов, и используйте непрерывное интеграционное тестирование, чтобы гарантировать совместимость с нужными версиями Python28- Если у вас есть зависимости, проверьте их статус Python 3 с помощью caniusepython3 ([инструмент командной строки](https://python-all.ru/3.3/howto/pyporting.html), [веб-приложение](https://python-all.ru/3.3/howto/pyporting.html))2930После этого доступны следующие варианты:3132- Если вы отказываетесь от поддержки Python 2, используйте [2to3](https://python-all.ru/3.3/howto/pyporting.html) для переноса на Python 333- If you are keeping Python 2 support, then start writing Python 2/3-compatible code starting **TODAY**3435  - Если у вас есть не перенесённые зависимости, свяжитесь с их авторами для переноса их проекта, а тем временем делайте свой код совместимым с Python 3, чтобы быть готовым, когда все зависимости будут перенесены36  - Если все ваши зависимости перенесены (или у вас их нет), смело переносите на Python 337- Если вы создаёте новый проект, который должен быть совместим с 2/3, пишите код на Python 3, а затем портируйте обратно на Python 23839## Перед началом4041Если ваш проект находится на [Cheeseshop](https://python-all.ru/3.3/howto/pyporting.html)/[PyPI](https://python-all.ru/3.3/howto/pyporting.html), убедитесь, что у него есть правильные [trove-классификаторы](https://python-all.ru/3.3/howto/pyporting.html), чтобы указать, какие версии Python он **в настоящее время** поддерживает. Как минимум, вы должны указать основную версию (версии), например `Programming Language :: Python :: 2`, если ваш проект в настоящее время поддерживает только Python 2. Предпочтительно быть максимально конкретным, перечислив каждую основную/дополнительную версию Python, которую вы поддерживаете, например, если ваш проект поддерживает Python 2.6 и 2.7, то вам нужны классификаторы:4243```python44Programming Language :: Python :: 245Programming Language :: Python :: 2.646Programming Language :: Python :: 2.747```4849Как только ваш проект будет поддерживать Python 3, вам нужно будет вернуться и добавить соответствующие классификаторы для Python 3. Это важно, так как установка классификатора `Programming Language :: Python :: 3` приведёт к тому, что ваш проект будет указан в разделе [Python 3 Packages](https://python-all.ru/3.3/howto/pyporting.html) на PyPI.5051Убедитесь, что у вас есть надёжный набор тестов. Нужно гарантировать, что всё продолжает работать, как и при поддержке нового минорного/функционального релиза Python. Это означает, что ваш набор тестов должен быть тщательным и правильно перенесён между Python 2 и 3 (рассмотрите использование [coverage](https://python-all.ru/3.3/howto/pyporting.html) для измерения эффективного покрытия тестами). Скорее всего, вам также захочется использовать что-то вроде [tox](https://python-all.ru/3.3/howto/pyporting.html) для автоматизации тестирования на всех поддерживаемых версиях Python. Кроме того, **сначала перенесите тесты**, чтобы вовремя обнаружить поломки во время перехода. Тесты, как правило, проще, чем тестируемый код, поэтому они дают представление о том, насколько легко может быть перенос кода.5253По возможности откажитесь от поддержки старых версий Python. [Python 2.5](https://python-all.ru/3.3/howto/pyporting.html) ввёл много полезного синтаксиса и библиотек, которые стали идиоматичными в Python 3. [Python 2.6](https://python-all.ru/3.3/howto/pyporting.html) ввёл future-инструкции, что значительно упрощает совместимость при переходе с Python 2 на 3. [Python 2.7](https://python-all.ru/3.3/howto/pyporting.html) продолжает эту тенденцию в стандартной библиотеке. Выберите самую новую версию Python, которую вы считаете минимально поддерживаемой, и работайте от неё.5455Нацеливайтесь на самую новую версию Python 3, какую только можете. Помимо обычных исправлений ошибок, совместимость между Python 2 и 3 со временем продолжала улучшаться. Например, Python 3.3 вернул префикс `u` для строк, что упрощает написание исходно-совместимого кода Python.5657## Написание совместимого кода на Python 2 и 35859За эти годы сообщество Python обнаружило, что самый простой способ параллельно поддерживать Python 2 и 3 – писать код Python, который работает в обеих версиях. Хотя поначалу это может показаться нелогичным, на самом деле это несложно и обычно требует лишь соблюдения некоторых (неидиоматичных) практик и использования ключевых проектов, упрощающих переход между Python 2 и 3.6061### Проекты, которые стоит рассмотреть6263Библиотекой самого низкого уровня для одновременной поддержки Python 2 и 3 является [six](https://python-all.ru/3.3/howto/pyporting.html). Чтение её документации даст вам представление о том, какие именно изменения произошли в языке Python между версиями 2 и 3, и, следовательно, какую помощь вы захотите получить от библиотеки для продолжения поддержки.6465Чтобы автоматизировать перенос вашего кода на использование six, вы можете воспользоваться [modernize](https://python-all.ru/3.3/howto/pyporting.html). Этот проект попытается переписать ваш код максимально современно, используя six для сглаживания любых различий между Python 2 и 3.6667Если вы хотите, чтобы ваш совместимый код выглядел более похожим на Python 3, существует проект [future](https://python-all.ru/3.3/howto/pyporting.html). Он пытается предоставить обратные переносы (backports) объектов из Python 3, чтобы вы могли использовать их в коде, совместимом с Python 2, например, заменить тип `bytes` из Python 2 на соответствующий тип из Python 3. Он также предоставляет скрипт перевода, подобный modernize (его код перевода частично основан на modernize), чтобы помочь начать работу с существующей кодовой базой. Он также уникален тем, что его скрипт перевода может переносить код Python 3 обратно, а код Python 2 – вперёд.6869### Советы и хитрости7071Чтобы упростить написание совместимого с исходным кодом кода с использованием одного из проектов, упомянутых в [Projects to Consider](https://python-all.ru/3.3/howto/pyporting.html#projects-to-consider), следуйте приведённым ниже рекомендациям. Некоторые из них уже обрабатываются рекомендуемыми проектами, поэтому если вы используете один из них, сначала прочитайте его документацию, чтобы узнать, какие из приведённых ниже советов будут выполнены автоматически.7273#### Поддержка Python 2.77475На первом шаге убедитесь, что ваш проект совместим с [Python 2.7](https://python-all.ru/3.3/howto/pyporting.html). Это просто хорошо сделать, поскольку Python 2.7 – последний релиз Python 2, и поэтому он будет использоваться довольно долго. Это также позволяет использовать флаг `-3` для Python, чтобы помочь обнаружить места в коде, где может быть проблема совместимости (флаг `-3` присутствует в Python 2.6, но Python 2.7 добавляет больше предупреждений).7677#### Старайтесь поддерживать только [Python 2.6](https://python-all.ru/3.3/howto/pyporting.html) и новее7879While not possible for all projects, if you can support [Python 2.6](https://python-all.ru/3.3/howto/pyporting.html) and newer **only**, your life will be much easier. Various future statements, stdlib additions, etc. exist only in Python 2.6 and later which greatly assist in supporting Python 3. But if you project must keep support for [Python 2.5](https://python-all.ru/3.3/howto/pyporting.html) then it is still possible to simultaneously support Python 3.8081Ниже перечислены преимущества, которые вы получаете, если вам нужно поддерживать только Python 2.6 и новее. Некоторые из этих вариантов являются личным выбором, тогда как другие **настоятельно** рекомендуются (те, которые больше относятся к личному выбору, помечены как таковые). Если вы продолжаете поддерживать более старые версии Python, то вам, по крайней мере, нужно следить за ситуациями, которые эти решения исправляют, и обрабатывать их соответствующим образом (в этом случае помощь библиотек, например [six](https://python-all.ru/3.3/howto/pyporting.html), оказывается очень кстати).8283##### `from __future__ import print_function`8485Это не только приучает писать `print()` как функцию вместо оператора, но и даёт все преимущества, которые функция имеет по сравнению с оператором Python 2 ([six](https://python-all.ru/3.3/howto/pyporting.html) предоставляет функцию, если поддерживается Python 2.5 или старше).8687##### `from __future__ import unicode_literals`8889Если используется этот future-оператор, то все строковые литералы в Python 2 будут считаться Unicode (как уже происходит в Python 3). Если не использовать этот future-оператор, то следует помечать все текстовые строки префиксом `u` и поддерживать только Python 3.3 или новее. Но **настоятельно** рекомендуется сделать что-то одно ([six](https://python-all.ru/3.3/howto/pyporting.html) предоставляет функцию, если не хочется использовать future-оператор **и** требуется поддержка Python 3.2 или старше).9091##### Байтовые/строковые литералы9293Это **очень** важный момент. Добавляйте префикс `b` к строкам Python 2, которые предназначены для хранения байтов, чтобы чётко разграничить, что является, а что не является текстовой строкой Python 3 ([six](https://python-all.ru/3.3/howto/pyporting.html) предоставляет функцию для совместимости с Python 2.5).9495Этот момент нельзя переоценить: убедитесь, что вы знаете, какими должны быть все ваши строковые литералы Python 2 в Python 3. Любой строковый литерал, который должен обрабатываться как байты, должен иметь префикс `b`. Любой строковый литерал, который должен быть Unicode/текстом в Python 2, должен либо иметь литерал `u` (поддерживается, но игнорируется в Python 3.3 и новее), либо в начале файла должно быть `from __future__ import unicode_literals`. Но ключевой момент – вы должны знать, как Python 3 будет обрабатывать каждый ваш строковый литерал, и помечать их соответствующим образом.9697Существуют некоторые различия между байтовыми литералами в Python 2 и Python 3 из-за того, что в Python 2 тип bytes является просто псевдонимом `str`. Смотрите раздел [Handle Common “Gotchas”](https://python-all.ru/3.3/howto/pyporting.html#handle-common-gotchas), чтобы знать, чего остерегаться.9899##### `from __future__ import absolute_import`100101Более подробно обсуждается ниже, но вам следует использовать этот future-оператор, чтобы случайно не применить неявные относительные импорты.102103#### Поддержка только [Python 2.5](https://python-all.ru/3.3/howto/pyporting.html) и новее104105Если вы поддерживаете [Python 2.5](https://python-all.ru/3.3/howto/pyporting.html) и новее, всё ещё есть некоторые возможности Python, которые можно использовать.106107##### `from __future__ import absolute_import`108109Неявные относительные импорты (например, импорт `spam.bacon` из `spam.eggs` с помощью оператора `import bacon`) не работают в Python 3. Этот future-оператор отходит от этого и позволяет использовать явные относительные импорты (например, `from . import bacon`).110111В [Python 2.5](https://python-all.ru/3.3/howto/pyporting.html) необходимо использовать оператор \_\_future\_\_, чтобы иметь возможность использовать явные относительные импорты и предотвратить неявные. В [Python 2.6](https://python-all.ru/3.3/howto/pyporting.html) явные относительные импорты доступны и без этого оператора, но всё равно стоит использовать оператор \_\_future\_\_ для предотвращения неявных относительных импортов. В [Python 2.7](https://python-all.ru/3.3/howto/pyporting.html) оператор \_\_future\_\_ не нужен. Другими словами, если вы не поддерживаете только Python 2.7 или версию старше 2.5, используйте этот оператор \_\_future\_\_.112113##### Помечайте все строки Unicode префиксом `u`114115Хотя в Python 2.6 есть оператор `__future__`, который автоматически заставляет Python 2 обрабатывать все строковые литералы как Unicode, в Python 2.5 такого сокращённого пути нет. Это означает, что вам нужно просмотреть все строковые литералы и пометить их префиксом `u`, чтобы явно превратить их в текстовые строки, где это необходимо, и поддерживать только Python 3.3 или новее. В противном случае используйте проект вроде [six](https://python-all.ru/3.3/howto/pyporting.html), который предоставляет функцию для обработки всех текстовых строковых литералов.116117##### Перехват текущего возбуждённого исключения118119В Python 2.5 и ранее синтаксис для доступа к текущему исключению:120121```python122try:123  raise Exception()124except Exception, exc:125  # Текущее исключение: 'exc'.126  pass127```128129Этот синтаксис изменился в Python 3 (и был перенесён в [Python 2.6](https://python-all.ru/3.3/howto/pyporting.html) и новее) на:130131```python132try:133  raise Exception()134except Exception as exc:135  # Текущее исключение: 'exc'.136  # В Python 3 'exc' ограничено блоком; в Python 2.6/2.7 оно "утекает".137  pass138```139140Из-за этого изменения синтаксиса необходимо изменить способ перехвата текущего исключения в Python 2.5 и ранее на:141142```python143try:144  raise Exception()145except Exception:146  import sys147  exc = sys.exc_info()[1]148  # Текущее исключение: 'exc'.149  pass150```151152Из [`sys.exc_info()`](https://python-all.ru/3.3/library/sys.html#sys.exc_info) можно получить больше информации о возбуждённом исключении, чем просто экземпляр текущего исключения, но, скорее всего, она не нужна.153154> **Примечание**155>156> В Python 3 трассировка прикрепляется к экземпляру исключения через атрибут `__traceback__`. Если экземпляр сохраняется в локальной переменной, которая существует за пределами блока `except`, трассировка создаст циклическую ссылку с текущим фреймом и его словарём локальных переменных. Это задержит освобождение мёртвых ресурсов до следующего прохода циклической [*сборки мусора*](https://python-all.ru/3.3/glossary.html#term-garbage-collection).157>158> В Python 2 эта проблема возникает только в том случае, если сохранить саму трассировку (например, третий элемент кортежа, возвращаемого [`sys.exc_info()`](https://python-all.ru/3.3/library/sys.html#sys.exc_info)) в переменной.159160#### Работа с распространёнными «подводными камнями»161162Это вещи, на которые следует обращать внимание независимо от поддерживаемой версии Python 2, и они не относятся к синтаксису.163164##### `from __future__ import division`165166Хотя того же результата можно добиться, используя аргумент `-Qnew` Python, использование этого future-оператора снимает требование, чтобы пользователи использовали этот флаг для получения ожидаемого поведения деления в Python 3 (например, `1/2 == 0.5; 1//2 == 0`).167168##### Указывайте при открытии файла в двоичном режиме169170Если вы не работали в Windows, возможно, вы не всегда утруждали себя добавлением режима `b` при открытии двоичного файла (например, `rb` для чтения в двоичном режиме). В Python 3 двоичные файлы и текстовые файлы чётко различаются и взаимно несовместимы; подробнее см. модуль [`io`](https://python-all.ru/3.3/library/io.html#module-io). Поэтому **необходимо** принять решение, будет ли файл использоваться для двоичного доступа (чтение и/или запись байтовых данных) или текстового доступа (чтение и/или запись данных Unicode).171172##### Текстовые файлы173174Текстовые файлы, созданные с помощью `open()` в Python 2, возвращают байтовые строки, тогда как в Python 3 они возвращают строки Unicode. В зависимости от стратегии переноса это может быть проблемой.175176Если требуется, чтобы текстовые файлы возвращали строки Unicode в Python 2, есть две возможности:177178- В Python 2.6 и выше используйте [`io.open()`](https://python-all.ru/3.3/library/io.html#io.open). Поскольку [`io.open()`](https://python-all.ru/3.3/library/io.html#io.open) по сути та же функция и в Python 2, и в Python 3, это поможет устранить любые возможные проблемы.179- Если требуется совместимость с версиями ниже 2.6, тогда используйте [`codecs.open()`](https://python-all.ru/3.3/library/codecs.html#codecs.open). Это гарантирует, что в Python 2 вы получите строки Unicode.180181##### Наследуйте от `object`182183Классы нового стиля существуют с [Python 2.2](https://python-all.ru/3.3/howto/pyporting.html). Необходимо убедиться, что вы наследуете от `object`, чтобы избежать странных крайних случаев с порядком разрешения методов и т.д. Это по-прежнему полностью допустимо в Python 3 (хотя и не нужно, так как все классы неявно наследуют от `object`).184185##### Работа с дихотомией байтов и строк186187Одна из самых больших проблем при портировании кода на Python 3 – это обработка дихотомии байтов и строк. Поскольку Python 2 позволял типу `str` хранить текстовые данные, люди со временем стали довольно небрежно разграничивать, какие экземпляры `str` содержат текст, а какие – байты. В Python 3 уже нельзя быть таким беспечным, и необходимо правильно обрабатывать разницу. Ключ к решению этой проблемы – убедиться, что **каждый** строковый литерал в вашем коде Python 2 помечен синтаксически или функционально как байтовые или текстовые данные. После этого нужно убедиться, что ваши API спроектированы так, чтобы либо обрабатывать конкретный тип, либо быть правильно полиморфными.188189###### Разметка строковых литералов Python 2190191Первое, что нужно сделать – обозначить каждый строковый литерал в Python 2 как текстовый или байтовый. Если вы поддерживаете только Python 2.6 или новее, это можно сделать, пометив байтовые литералы префиксом `b`, а текстовые – префиксом `u` или с помощью future-оператора `unicode_literals`.192193Если ваш проект поддерживает версии Python до 2.6, тогда следует использовать проект [six](https://python-all.ru/3.3/howto/pyporting.html) и его функцию `b()` для обозначения байтовых литералов. Для текстовых литералов можно использовать функцию `u()` из six или префикс `u`.194195###### Определите, что будут принимать API196197В Python 2 было очень легко случайно создать API, который принимал как байтовые, так и текстовые данные. Но в Python 3, благодаря более строгой обработке разнотипных данных, такое свободное использование байтов и текста вместе обычно приводит к ошибкам.198199Возьмем словарь `{b'a': 'bytes', u'a': 'text'}` в Python 2.6. Он создает словарь `{u'a': 'text'}`, так как `b'a' == u'a'`. Но в Python 3 эквивалентный словарь создает `{b'a': 'bytes', 'a': 'text'}`, т.е. без потери данных. Подобные проблемы могут возникать при переносе кода Python 2 на Python 3.200201Это означает, что нужно выбрать, что API будет принимать и создавать, и последовательно придерживаться этого API в Python 2 и 3.202203###### Сравнение байтов и Unicode204205В Python 3 смешивание байтов и unicode запрещено в большинстве ситуаций; это вызовет [`TypeError`](https://python-all.ru/3.3/library/exceptions.html#TypeError), тогда как Python 2 попытался бы выполнить неявное приведение типов. Однако есть один случай, когда это не так, и это может ввести в заблуждение:206207```python208>>> b"" == ""209False210```211212Это потому, что сравнение на равенство по языку всегда должно завершаться успехом (и возвращать `False` для несовместимых типов). Однако это также означает, что неправильно портированный код на Python 3 может демонстрировать ошибочное поведение, если такие сравнения выполняются незаметно. Для обнаружения таких ситуаций в Python 3 есть флаг `-b`, который будет показывать предупреждение:213214```python215$ python3 -b216>>> b"" == ""217__main__:1: BytesWarning: Comparison between bytes and string218False219```220221Чтобы превратить предупреждение в исключение, используйте флаг `-bb`:222223```python224$ python3 -bb225>>> b"" == ""226Traceback (most recent call last):227  File "<stdin>", line 1, in <module>228BytesWarning: Comparison between bytes and string229```230231##### Индексирование байтовых объектов232233Еще одно потенциально удивительное изменение – это поведение индексирования байтовых объектов в Python 3:234235```python236>>> b"xyz"[0]237120238```239240Действительно, байтовые объекты Python 3 (а также объекты [`bytearray`](https://python-all.ru/3.3/library/functions.html#bytearray)) являются последовательностями целых чисел. Но код, перенесенный из Python 2, часто предполагает, что индексирование байтовой строки дает другую байтовую строку, а не целое число. Чтобы согласовать оба поведения, используйте срезы:241242```python243>>> b"xyz"[0:1]244b'x'245>>> n = 1246>>> b"xyz"[n:n+1]247b'y'248```249250Единственная оставшаяся ловушка в том, что выход за границы при срезе возвращает пустой байтовый объект вместо возбуждения `IndexError`:251252```python253>>> b"xyz"[3]254Traceback (most recent call last):255  File "<stdin>", line 1, in <module>256IndexError: index out of range257>>> b"xyz"[3:4]258b''259```260261##### `__str__()`/`__unicode__()`262263В Python 2 объекты могут определять как строковое, так и unicode представление себя. В Python 3, однако, существует только строковое представление. Это становится проблемой, поскольку люди могут нечаянно делать в своих методах `__str__()` вещи, которые приводят к непредсказуемым результатам (например, бесконечная рекурсия, если использовать идиому `unicode(self).encode('utf8')` в качестве тела метода `__str__()`).264265Можно использовать mixin-класс для обхода этого. Это позволяет определить только метод `__unicode__()` для вашего класса, а mixin выведет `__str__()` за вас (код из [http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/](https://python-all.ru/3.3/howto/pyporting.html)):266267```python268import sys269270class UnicodeMixin(object):271272  """Миксин-класс для определения правильных методов __str__/__unicode__273  методов в Python 2 или 3.274275  if sys.version_info[0] >= 3: # Python 3276      def __str__(self):277          return self.__unicode__()278  else:  # Python 2279      def __str__(self):280          return self.__unicode__().encode('utf8')281282class Spam(UnicodeMixin):283284  def __unicode__(self):285      return u'spam-spam-bacon-spam'  # 2to3 удалит префикс 'u'.286```287288##### Не индексируйте исключения289290В Python 2 следующее работало:291292```python293>>> exc = Exception(1, 2, 3)294>>> exc.args[1]2952296>>> exc[1]  # Только Python 2!2972298```299300Но в Python 3 индексирование непосредственно исключения является ошибкой. Необходимо убедиться, что индексирование производится только по атрибуту [`BaseException.args`](https://python-all.ru/3.3/library/exceptions.html#BaseException.args), который представляет собой последовательность, содержащую все аргументы, переданные методу [`__init__()`](https://python-all.ru/3.3/reference/datamodel.html#object.__init__).301302Еще лучше использовать документированные атрибуты, которые предоставляет исключение.303304##### Не используйте `__getslice__` и компанию305306Уже некоторое время считалось устаревшим, но Python 3 наконец отказался от поддержки `__getslice__()` и т.д. Полностью переходите на [`__getitem__()`](https://python-all.ru/3.3/reference/datamodel.html#object.__getitem__) и ее друзей.307308##### Обновление doctest-ов309310Не забывайте также делать их совместимыми с Python 2/3. Если вы написали монолитный набор доктестов (например, одну строку документации, содержащую все доктесты), вам стоит хотя бы подумать о разбиении доктестов на более мелкие части, чтобы их было проще исправлять. В противном случае, возможно, стоит потратить время и усилия на перенос тестов в [`unittest`](https://python-all.ru/3.3/library/unittest.html#module-unittest).311312##### Обновление `map` для несбалансированных входных последовательностей313314В Python 2, когда `map` передавалось более одной входной последовательности, он дополнял более короткие последовательности значениями *None*, возвращая последовательность такой же длины, как самая длинная входная последовательность.315316В Python 3, если входные последовательности для `map` имеют разную длину, `map` остановится по завершении самой короткой из последовательностей. Для полной совместимости с `map` из Python 2.x оберните аргументы последовательностей в [`itertools.zip_longest()`](https://python-all.ru/3.3/library/itertools.html#itertools.zip_longest), например `map(func, *sequences)` становится `list(map(func, itertools.zip_longest(*sequences)))`.317318### Устранение `-3` предупреждений319320При запуске тестового набора вашего приложения запускайте его с флагом `-3`, переданным Python. Это вызовет различные предупреждения во время выполнения о вещах, которые являются семантическими изменениями между Python 2 и 3. Постарайтесь устранить эти предупреждения, чтобы сделать ваш код ещё более переносимым на Python 3.321322## Альтернативные подходы323324Хотя одновременная поддержка Python 2 и 3 обычно является предпочтительным выбором, чтобы можно было продолжать улучшать код и работать для наибольшего числа пользователей, ваша жизнь может стать проще, если в будущем вам нужно будет поддерживать только одну основную версию Python.325326### Поддержка только Python 3 в будущем из кода на Python 2327328Если у вас есть код на Python 2, но в будущем вы хотите улучшать его только как код на Python 3, то вы можете использовать [2to3](https://python-all.ru/3.3/howto/pyporting.html) для перевода вашего кода с Python 2 на Python 3. Это рекомендуется только в том случае, если текущая версия вашего проекта переходит в режим поддержки и вы хотите, чтобы все новые функции были эксклюзивными для Python 3.329330### Перенос кода с Python 3 на Python 2331332Если у вас есть код на Python 3 и вы не заинтересованы в поддержке Python 2, вы можете использовать [3to2](https://python-all.ru/3.3/howto/pyporting.html) для перевода с Python 3 на Python 2. Это рекомендуется только в том случае, если вы не планируете активно поддерживать пользователей Python 2. В противном случае пишите свой код для Python 3, а затем переносите его обратно настолько далеко, насколько хотите. Обычно это проще, чем переход с Python 2 на 3, поскольку вы уже решите все трудности, например, с байтами/строками и т.д.333334## Другие ресурсы335336Авторы следующих постов в блогах, страниц вики и книг заслуживают особой благодарности за публикацию своих советов по переносу кода с Python 2 на Python 3 (и, таким образом, за помощь в предоставлении информации для этого документа и его различных редакций на протяжении многих лет):337338- [http://wiki.python.org/moin/PortingPythonToPy3k](https://python-all.ru/3.3/howto/pyporting.html)339- [http://python3porting.com/](https://python-all.ru/3.3/howto/pyporting.html)340- [http://docs.pythonsprints.com/python3\_porting/py-porting.html](https://python-all.ru/3.3/howto/pyporting.html)341- [http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/](https://python-all.ru/3.3/howto/pyporting.html)342- [http://dabeaz.blogspot.com/2011/01/porting-py65-and-my-superboard-to.html](https://python-all.ru/3.3/howto/pyporting.html)343- [http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/](https://python-all.ru/3.3/howto/pyporting.html)344- [http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/](https://python-all.ru/3.3/howto/pyporting.html)345- [https://wiki.ubuntu.com/Python/3](https://python-all.ru/3.3/howto/pyporting.html)346347Если вы считаете, что в этом документе чего-то не хватает и это следует добавить, отправьте письмо в список рассылки [python-porting](https://python-all.ru/3.3/howto/pyporting.html).348