Intermediate Python
  • Introduction
  • Средства разработки
    • Виртуальное окружение
    • Отладка
    • Анализ объекта
  • Синтаксис
    • Исключения
    • for - else
    • Тернарные операторы
    • global и return
    • Функция open
    • *args и **kwargs
    • Менеджеры контекста
  • Функциональное программирование
    • enumerate
    • Анонимные функции
    • Структура данных set
    • map и filter
    • Абстракция списков
  • Структуры данных
    • Генераторы
    • Корутины
    • Классы
  • Типы данных
    • collections
    • Изменяемость
    • Магия __slots__
  • Декораторы
    • Что такое декоратор?
    • Кэширование функций
  • Разное
    • Однострочники
    • Python C расширения
    • Разработка под Python 2+3
Powered by GitBook
On this page
  • Импорты Future
  • Переименование модулей
  • Заменяем устаревшие модули Python 2
  • Сторонние бэкпорты
  1. Разное

Разработка под Python 2+3

Во многих случаях вам может понадобиться писать программы, которые будут корректно работать и на Python 2+ и на 3+.

Представьте, что у вас есть крайне популярный Python-пакет, который используют тысячи людей, но не у всех есть Python 2 или Python 3. В этом случае у вас есть два варианта. Первый - разрабатывать две версии параллельно, одну для второй ветки Python, а другую - для третьей. Другим вариантом будет изменение текущего кода для совместимости как с Python 2, так и с Python 3.

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

Импорты Future

Первым и наиболее важным методом будет использование импорта __future__. Это позволяет вам импортировать функционал Python 3 в Python 2. Ниже несколько примеров.

Менеджеры контекста были нововведением в Python 2.6+. Для их использования в Python 2.5 вам необходимо:

from __future__ import with_statement

print стал функцией в Python 3. Для её использования в Python 2 вы можете импортировать функцию из __future__:

print
# Вывод:

from __future__ import print_function
print(print)
# Вывод: <built-in function print>

Переименование модулей

Для начала, скажите мне как вы импортируете модули в ваших скриптах? Большинство делает так:

import foo
# или
from foo import bar

А знаете ли вы про такой способ:

import foo as foo

Я знаю, что эффект будет такой же, как и в первом случае, но этот способ критичен для совместимости программ с Python 2 и 3. Попробуем следующий код:

try:
    import urllib.request as urllib_request  # для Python 3
except ImportError:
    import urllib2 as urllib_request  # для Python 2

Позвольте мне немного пояснить. Мы используем блок try/except для импорта. Причина - в Python 2 нет модуля urllib.request, поэтому попытка его импорта приведет к ImportError. Функциональность urllib.request доступна в модуле urlib2 в Python 2. Таким образом, при использовании Python 2, при импорте urllib.request мы упираемся в Exception и импортируем urllib2 в качестве альтернативы.

Последнее что вам нужно знать - ключевое слово as. С его помощью мы импортируем модуль под именем urllib_request. Дальше в коде мы просто будем ссылаться на это имя, вне зависимости от того, какую ветку Python мы используем.

Заменяем устаревшие модули Python 2

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

from future.builtins.disabled import *

Теперь, при использовании удаленного в Python 3 модуля, мы будем получать NameError:

from future.builtins.disabled import *

apply()
# Вывод: NameError: obsolete Python 2 builtin apply is disabled

Сторонние бэкпорты

Существует несколько пакетов, которые предоставляют новый функционал Python 3 в Python 2. Например:

  • enum pip install enum34

  • singledispatch pip install singledispatch

  • pathlib pip install pathlib

PreviousPython C расширения

Last updated 6 years ago

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

исчерпывающее руководство