«Кошелек или деньги: сложный выбор между памятью и процессором» Алексеенко Иг...
ekbpy'2012 - Михаил Коробов - Python 3
1. Python 3
фичи и проблемы портирования
Михаил Коробов,
EKBPY, 10 февраля 2012
2. Немного истории
● апрель 2006 - PEP 3000
● декабрь 2008 - Python 3.0
● июль 2010 - последний релиз с новыми
фичами в ветке 2.х
● май 2011 - закончилась поддержка 2.5
(больше нет даже обновлений
безопасности)
● 2013 - закончится поддержка 2.6
● 2016 (?) - закончится поддержка 2.7
3. Зачем переходить на 3.x?
Когда переходить на 3.x?
Переходить ли на 3.х?
Как переходить?
5. Улучшения в стандартной
библиотеке
В 2.x с лета 2010 года (выход 2.7)
улучшений в стандартной библиотеке нет.
И не будет больше.
Только исправление ошибок.
6. Unicode
● 2.x: неявное преобразование между
юникодными и байтовыми строками
иногда вызывает исключение.
● 3.х: неявное преобразование между
юникодными и байтовыми строками
всегда вызывает исключение.
см. также: https://github.com/mitsuhiko/unicode-nazi
7. Unicode
● вся стандартная библиотека работает с
юникодом (см., например, csv в 2.x)
● # --* coding: utf-8 *--
● def вася(параметр1, параметр2): pass
3.3 (выйдет этим летом): более
эффективное хранение unicode-строк
9. Классы
● Больше нет разделения на old-style и
new-style;
● другой синтаксис для метаклассов (плюс
поддержка kwargs в объявлении классов);
● super
cм. https://github.com/rfk/magicsuper и http://pypi.python.
org/pypi/newsuper
10. Классы: 2.x
class Foo(object):
def do(self):
return 41
class Bar(Foo):
__metaclass__ = Meta
def do(self):
old = super(Bar, self).do()
return old + 1
11. Классы: 3.x
class Foo:
def do(self):
return 41
class Bar(Foo, metaclass=Meta):
def do(self):
old = super().do()
return old + 1
21. Потоки (threads)
● Более быстрый GIL (Python 3.2);
● Исправлены некоторые недочеты
реализации в 2.х - например, в 2.x поток,
застрявший в deadlock'е, нельзя убить по
SIGINT (Ctrl-C), а в 3.2 - можно.
22. yield from
# python 2.x
def gen1():
yield 'foo'
yield 'bar'
def gen2():
for x in gen():
yield x
24. yield from: зачем?
С помощью yield можно писать на Python
асинхронный код в синхронном стиле (без
вороха callback'ов); yield from делает это
проще.
См. также:
● twisted.internet.defer.deferredGenerator;
● tornado.gen;
● https://launchpad.net/adisp
31. Просто взять и переписать на 3.х
● (+) лучшая стратегия перевода "своего"
кода;
● (-) нужно переписывать весь код на 3.х;
● (-) нельзя использовать сторонний код,
написанный для 2.х;
● (-) не подходит для open-source
библиотек, которым важна обратная
совместимость (привет dateutil)
32. Библиотеки
● Чтоб на практике использовать Python 3,
нужны библиотеки, поддерживающие
Python 3;
● переписать библиотеки с 2.х на 3.х
нельзя, т.к. большая часть кода пишется
на 2.х и поэтому поддержка 2.х важна.
● Чтобы писать код на Python 3 и
использовать сторонние наработки, нужно
уметь добавлять поддержку 3.х в код на 2.
х.
33. Проблема не в портировании
своего кода (взял да переписал),
проблема в портировании
библиотек
34. Экзотические способы
● писать на Cython (пример: lxml - большая
часть написана на Cython и поэтому
поддерживает и 2.x, и 3.х)
● пожертвовать 100k$ pypy и, возможно,
через год-другой получить интерпретатор,
который умеет как 2.х, так и 3.х
одновременно.
36. 2to3
Берет код на 2.х и преобразует его в код на
3.х автоматически.
● Можно применить 1 раз и работать потом
только с 3.х кодом;
● можно вести разработку на 2.х и получать
версию 3.х при необходимости (setup.py).
38. 2to3: плюсы
● Входит в стандартную поставку и
рекомендуется в PEP-3000;
● автоматически генерирует 3.х код из 2.х
кода;
● просто интегрируется с setup.py.
39. 2to3: минусы
● работает не всегда корректно, требует
ручного вмешательства или написания
своих "фиксеров";
● медленно работает;
● затруднена отладка при ошибках в 3.х
коде;
● при использовании в авто-режиме
разработка все еще ведется на 2.х
40. 3to2
2to3 наоборот: код пишется на 3.х,
автоматически генерируется версия для 2.х
● не входит в стандартную поставку;
● код пишется на 3.х, а не на 2.х;
● мало кто использует на практике.
42. Код, который работает как на 2.х,
так и на 3.х
● pyramid (1.3);
● django (trunk сразу после релиза 1.4);
● pip;
● virtualenv;
● WebOb;
● coverage;
● requests;
● python-код из lxml;
● whoosh;
● pytz;
● ...
43. Код, который работает как на 2.х,
так и на 3.х
● разработка ведется с использованием
подмножества python 2.x, совместимого с
3.х.
● отсутствует шаг с автоматической
генерацией кода, поэтому проще отладка
и разработка;
● поддержка python 2.5 требует хаков;
44. Код, который работает как на 2.х,
так и на 3.х
● Библиотека six (около 300 строк):
if PY3:
text_type = str
else:
text_type = unicode
# ...
● вся six целиком редко нужна (пример:
pymorphy.py3k - это 6 строк кода из six)
45. Необходимые условия для
портирования
● Автоматизированные тесты;
● по возможности, современные версии
языковых конструкций (желательно 2.6+);
● четкая стратегия работы с unicode;
46. Один из возможных алгоритмов
1. Удостовериться, что тестов достаточно;
2. настроить tox;
3. перестать поддерживать python 2.5;
4. заставить весь код работать с
from __future__ import (absolute_import,
unicode_literals, print_function, division)
5. "внутри" использовать только unicode-
строки;
6. чинить ошибки в 3.х с помощью six, пока
все не заработать и под 2, и под 3.
47. Больше ссылок
● http://wiki.python.org/moin/PortingPythonToPy3k
● https://code.djangoproject.com/wiki/PortingNotesFor2To3
● http://python3porting.com/
● http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/
● http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/
● http://docs.pythonsprints.com/python3_porting/index.html
● http://docs.python.org/release/3.0.1/whatsnew/3.0.html (там внизу -
способ портирования на python3 от Guido van Rossum)