
![Page 1: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/1.jpg)
1
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Compatibilidade entreCompatibilidade entrePython 2 e 3Python 2 e 3
Como portar seu códigoem Python 2.x
para o Python 3.xsem torná-lo incompatível
com o Python 2.x?
Com base na história do pacote AudioLazy
![Page 2: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/2.jpg)
2
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Por quê?Por quê?
● Versões futuras do PythonVersões futuras do Python● Ampliar o público-alvo de seu projetoAmpliar o público-alvo de seu projeto
– AudioLazyAudioLazy● https://pypi.python.org/pypi/audiolazy/https://pypi.python.org/pypi/audiolazy/
● Pressão social e tecnofílicos!Pressão social e tecnofílicos!– Software para uso científicoSoftware para uso científico
● NumPyNumPy● MatPlotLibMatPlotLib● SciPySciPy
– Notícias recentesNotícias recentes● Flask!Flask!
TODOS já são compatíveiscom o Python 3.x!
E outros 2800+ pacotes no PyPI...
Python 2.x is the status quo, Python 3.x is the present and future of the language.
www.python.org
![Page 3: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/3.jpg)
3
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Valores coletados dia 2013-10-02Alguns númerosAlguns números
Compatibilidade entre Python 2.7 e outras versões
Compatibilidade entre Python 3 e outras versões
![Page 4: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/4.jpg)
4
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Por onde começarPor onde começar
● Suíte de testesSuíte de testes● Conhecimento sobre Conhecimento sobre
as diferenças entre as diferenças entre versõesversões– Ler, estudarLer, estudar
– Fuçar, brincar, Fuçar, brincar, remoer, torturar a remoer, torturar a linguagemlinguagem
● Outras ferramentas e Outras ferramentas e pacotespacotes– Já solucionaram o mesmo Já solucionaram o mesmo
problema? Como?problema? Como?
– Pacotes de auxílio à Pacotes de auxílio à compatibilizaçãocompatibilização
– Dependências funcionam Dependências funcionam em quais versões do em quais versões do Python?Python?
● Diminuir restriçõesDiminuir restrições
![Page 5: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/5.jpg)
5
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Parte 1Parte 1Tipos de diferençasTipos de diferenças
![Page 6: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/6.jpg)
6
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Nomes e localizaçõesNomes e localizações
import Tkinter
master = Tkinter.Tk()master.mainloop()
import Tkinter
master = Tkinter.Tk()master.mainloop()
import tkinter
master = tkinter.Tk()master.mainloop()
import tkinter
master = tkinter.Tk()master.mainloop()
Apenas Python 2Apenas Python 2 Apenas Python 3Apenas Python 3
Traceback (most recent call last): [...]ImportError: No module named Tkinter
Traceback (most recent call last): [...]ImportError: No module named Tkinter
Rodando no Python 3Rodando no Python 3
Rodando no Python 2Rodando no Python 2
Traceback (most recent call last): [...]ImportError: No module named tkinter
Traceback (most recent call last): [...]ImportError: No module named tkinter
![Page 7: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/7.jpg)
7
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Nomes e localizaçõesNomes e localizaçõescom try...exceptcom try...except
try: import tkinterexcept ImportError: import Tkinter as tkinter
master = tkinter.Tk()master.mainloop()
try: import tkinterexcept ImportError: import Tkinter as tkinter
master = tkinter.Tk()master.mainloop()
● Nome únicoNome único– ““as” no importas” no import
– AtribuiçãoAtribuição
● Há critérios para uso do Há critérios para uso do nome?nome?– PEP8PEP8
– Nome no Python 3Nome no Python 3● Versões futurasVersões futuras
– Nome no Python 2Nome no Python 2● Atual hábitoAtual hábito● Ausente no Python 3Ausente no Python 3
Quais nomes foram “trocados”?
Quais nomes foram “trocados”?
Documentação para
Documentação para
desenvolvedores!desenvolvedores!
![Page 8: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/8.jpg)
8
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Módulo future_builtinsMódulo future_builtins
In [1]: import future_builtinsIn [2]: dir(future_builtins)Out[2]: ['__doc__', '__file__', '__name__', '__package__', 'ascii', 'filter', 'hex', 'map', 'oct', 'zip']
In [1]: import future_builtinsIn [2]: dir(future_builtins)Out[2]: ['__doc__', '__file__', '__name__', '__package__', 'ascii', 'filter', 'hex', 'map', 'oct', 'zip']
Fazer zip/map/filter do Python 2 funcionar como Fazer zip/map/filter do Python 2 funcionar como no Python 3 (módulo existe somente no Python 2)no Python 3 (módulo existe somente no Python 2)
try: from future_builtins import *except ImportError: pass # Python 3
try: from future_builtins import *except ImportError: pass # Python 3
![Page 9: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/9.jpg)
9
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
““Módulo” __future__Módulo” __future__
In [1]: import __future__In [2]: dir(__future__)Out[2]: [ ... , 'absolute_import', 'all_feature_names', 'division', 'generators', 'nested_scopes', 'print_function', 'unicode_literals', 'with_statement']
In [1]: import __future__In [2]: dir(__future__)Out[2]: [ ... , 'absolute_import', 'all_feature_names', 'division', 'generators', 'nested_scopes', 'print_function', 'unicode_literals', 'with_statement']
● Linha inicial de seu códigoLinha inicial de seu código– Importar antes de outros importsImportar antes de outros imports
● Existe no Python 2 e 3Existe no Python 2 e 3
![Page 10: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/10.jpg)
10
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Nomes e localizaçõesNomes e localizaçõescom verificação préviacom verificação prévia
● sys.version_infosys.version_info
● sys.modulessys.modules
import sys
PYTHON2 = sys.version_info.major == 2if PYTHON2: builtins = sys.modules["__builtin__"]else: import builtins
import sys
PYTHON2 = sys.version_info.major == 2if PYTHON2: builtins = sys.modules["__builtin__"]else: import builtins
![Page 11: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/11.jpg)
11
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Módulo sysMódulo sysIn [1]: import sys
In [2]: sys.version_infoOut[2]: sys.version_info(major=3, minor=2, micro=4, releaselevel='final', serial=0)
In [3]: sys.version_info >= (3, 2)Out[3]: True
In [4]: sys.version_info >= (3, 3)Out[4]: False
In [5]: sys.versionOut[5]: '3.2.4 (default, May 8 2013, 20:55:18) \n[GCC 4.7.3]'
In [1]: import sys
In [2]: sys.version_infoOut[2]: sys.version_info(major=3, minor=2, micro=4, releaselevel='final', serial=0)
In [3]: sys.version_info >= (3, 2)Out[3]: True
In [4]: sys.version_info >= (3, 3)Out[4]: False
In [5]: sys.versionOut[5]: '3.2.4 (default, May 8 2013, 20:55:18) \n[GCC 4.7.3]'
![Page 12: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/12.jpg)
12
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Nomes e localizaçõesNomes e localizaçõescom getattrcom getattr
● Funções são objetosFunções são objetos● Análogo ao método “get” de dicionáriosAnálogo ao método “get” de dicionários
import itertools
xzip = getattr(itertools, "izip", zip)xmap = getattr(itertools, "imap", map)xfilter = getattr(itertools, "ifilter", filter)
# Usando o builtins visto anteriormentexrange = getattr(builtins, "xrange", range)
import itertools
xzip = getattr(itertools, "izip", zip)xmap = getattr(itertools, "imap", map)xfilter = getattr(itertools, "ifilter", filter)
# Usando o builtins visto anteriormentexrange = getattr(builtins, "xrange", range)
![Page 13: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/13.jpg)
13
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Monkeypatch / MockMonkeypatch / Mock
● Usando getattr e atribuiçõesUsando getattr e atribuições
● Compatibilizar código de terceiros sem mudá-losCompatibilizar código de terceiros sem mudá-los● Nem sempre é possível (tipos básicos)Nem sempre é possível (tipos básicos)
– e.g. Método to_bytes do int (apenas Python 3)e.g. Método to_bytes do int (apenas Python 3)
import operatoroperator.div = getattr(operator, "div", operator.truediv)
import operatoroperator.div = getattr(operator, "div", operator.truediv)
In [1]: (317215).to_bytes(5, "big")Out[1]: b'\x00\x00\x04\xd7\x1f'In [1]: (317215).to_bytes(5, "big")Out[1]: b'\x00\x00\x04\xd7\x1f'
![Page 14: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/14.jpg)
14
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Funções e outros objetos Funções e outros objetos ausentesausentes
● ReconstruirReconstruir
● Criar pela primeira vezCriar pela primeira vez– e.g. itertools.accumulatee.g. itertools.accumulate
● audiolazy.accumulateaudiolazy.accumulate
from functools import wraps
@wraps(range)def orange(*args, **kwargs): return list(range(*args, **kwargs))
from functools import wraps
@wraps(range)def orange(*args, **kwargs): return list(range(*args, **kwargs))
![Page 15: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/15.jpg)
15
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Métodos ausentesMétodos ausentes
● Iteração sobre dicionáriosIteração sobre dicionários
● Iterável VS IteradorIterável VS Iterador– Gotcha!Gotcha!
def iteritems(dictionary): try: return getattr(dictionary, "iteritems")() except AttributeError: return iter(getattr(dictionary, "items")())
def iteritems(dictionary): try: return getattr(dictionary, "iteritems")() except AttributeError: return iter(getattr(dictionary, "items")())
![Page 16: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/16.jpg)
16
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
str / intstr / intno Python 3no Python 3
● String?String?– str no Python 3str no Python 3
– (unicode, str) no Python 2(unicode, str) no Python 2● builtins.basestringbuiltins.basestring
● Inteiro?Inteiro?– int no Python 3int no Python 3
– (long, int) no Python 2(long, int) no Python 2
INT_TYPES = (int, getattr(builtins, "long", None)) \ if PYTHON2 else (int,)
print(isinstance(something_here, INT_TYPES))
INT_TYPES = (int, getattr(builtins, "long", None)) \ if PYTHON2 else (int,)
print(isinstance(something_here, INT_TYPES))
Utilização com
Utilização comisinstanceisinstance
![Page 17: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/17.jpg)
17
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
InternalidadesInternalidades
● Iteradores (e geradores)Iteradores (e geradores)– Método next no Python 2Método next no Python 2
– Método __next__ no Python 3Método __next__ no Python 3
● Avaliação “if obj:” segue um método de objAvaliação “if obj:” segue um método de obj– __nonzero__ no Python 2__nonzero__ no Python 2
– __bool__ no Python 3__bool__ no Python 3
● Função do método (“unbound”)Função do método (“unbound”)– Python 2Python 2
● classe.metodo.im_funcclasse.metodo.im_func● objeto.metodo.im_funcobjeto.metodo.im_func
– Python 3Python 3● classe.metodoclasse.metodo● objeto.metodo.__func__objeto.metodo.__func__
![Page 18: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/18.jpg)
18
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Parte 2Parte 2TestesTestes
![Page 19: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/19.jpg)
19
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
TestesTestes
● AutomatizadosAutomatizados– py.testpy.test
– nosenose
– unittestunittest
– doctestdoctest
● Cobertura de códigoCobertura de código– ConfiabilidadeConfiabilidade
– DependênciasDependências● skipskip● xfailxfail● Compatibilizar Compatibilizar
dependênciadependência
Testes passandoTestes passando
Testes falhandoTestes falhando
![Page 20: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/20.jpg)
20
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Skip automático comSkip automático compy.testpy.test
import pytest
def skipper(msg="There's something not supported " "in this environment"): def skip(*args, **kwargs): pytest.skip(msg.format(*args, **kwargs)) return skip
operator.div = getattr(operator, "div", skipper("There's no " "operator.div"))
import pytest
def skipper(msg="There's something not supported " "in this environment"): def skip(*args, **kwargs): pytest.skip(msg.format(*args, **kwargs)) return skip
operator.div = getattr(operator, "div", skipper("There's no " "operator.div"))
![Page 21: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/21.jpg)
21
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
toxtox
[tox]envlist = py26,py27
[testenv]deps=pytestcommands=py.test
[tox]envlist = py26,py27
[testenv]deps=pytestcommands=py.test
● ““Standardize testing in Python”Standardize testing in Python”● tox.initox.ini
![Page 22: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/22.jpg)
22
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Parte 3Parte 3Diferenças importantesDiferenças importantes
!
![Page 23: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/23.jpg)
23
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
MetaclassesMetaclasses
● Classe cujas instâncias são classesClasse cujas instâncias são classes● Sintaxe diferenciada no Python 2 e 3Sintaxe diferenciada no Python 2 e 3
# Python 3bases = (object,)MyMeta = typeclass A(*bases, metaclass=MyMeta): pass
# Python 2class A(*bases): __metaclass__ = MyMeta
# Python 3bases = (object,)MyMeta = typeclass A(*bases, metaclass=MyMeta): pass
# Python 2class A(*bases): __metaclass__ = MyMeta
![Page 24: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/24.jpg)
24
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
MetaclassesMetaclasses
● Solução padrão:Solução padrão:– Criar uma classe Criar uma classe
vazia usando a vazia usando a metaclasse, e colocá-metaclasse, e colocá-la junto às basesla junto às bases
● Problemas:Problemas:– Construtor da classe Construtor da classe
pode falharpode falhar
● Solução alternativaSolução alternativa– Metaclasse falsaMetaclasse falsa
● Única base da nova Única base da nova classeclasse
– Construtor da Construtor da metaclasse com 2 metaclasse com 2 comportamentoscomportamentos
● Antes da obtenção do Antes da obtenção do dicionário da classedicionário da classe
● Depois (real Depois (real instanciação)instanciação)
– Função audiolazy.metaFunção audiolazy.meta
![Page 25: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/25.jpg)
25
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães>>> class BadMeta(type):... def __new__(mcls, name, bases, namespace):... if "bad" not in namespace:... raise Exception("Oops, not bad enough")... value = len(name)... def really_bad(self):... return self.bad() * value... namespace["really_bad"] = really_bad... return super(BadMeta, mcls).__new__(mcls, name, bases,... namespace)...>>> class Bady(meta(object, metaclass=BadMeta)):... def bad(self):... return "HUA "...>>> class BadGuy(Bady):... def bad(self):... return "R"...>>> issubclass(BadGuy, Bady)True>>> Bady().really_bad() # value = 4'HUA HUA HUA HUA '>>> BadGuy().really_bad() # value = 6'RRRRRR'
>>> class BadMeta(type):... def __new__(mcls, name, bases, namespace):... if "bad" not in namespace:... raise Exception("Oops, not bad enough")... value = len(name)... def really_bad(self):... return self.bad() * value... namespace["really_bad"] = really_bad... return super(BadMeta, mcls).__new__(mcls, name, bases,... namespace)...>>> class Bady(meta(object, metaclass=BadMeta)):... def bad(self):... return "HUA "...>>> class BadGuy(Bady):... def bad(self):... return "R"...>>> issubclass(BadGuy, Bady)True>>> Bady().really_bad() # value = 4'HUA HUA HUA HUA '>>> BadGuy().really_bad() # value = 6'RRRRRR'
![Page 26: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/26.jpg)
26
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Função “meta”Função “meta”
def meta(*bases, **kwargs): metaclass = kwargs.get("metaclass", type) if not bases: bases = (object,) class NewMeta(type): def __new__(mcls, name, mbases, namespace): if name: return metaclass.__new__(metaclass, name, Bases, namespace) return super(NewMeta, mcls).__new__(mcls, "", mbases, {}) return NewMeta("", tuple(), {})
def meta(*bases, **kwargs): metaclass = kwargs.get("metaclass", type) if not bases: bases = (object,) class NewMeta(type): def __new__(mcls, name, mbases, namespace): if name: return metaclass.__new__(metaclass, name, Bases, namespace) return super(NewMeta, mcls).__new__(mcls, "", mbases, {}) return NewMeta("", tuple(), {})
● Passo 1 – Criar classe com metaclasse fakePasso 1 – Criar classe com metaclasse fake– Apenas para obter o “namespace”Apenas para obter o “namespace”
● Passo 2 – Usar a metaclasse fornecidaPasso 2 – Usar a metaclasse fornecida
![Page 27: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/27.jpg)
27
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
PrintPrint
● Python 2Python 2– Statement / comandoStatement / comando
– print >>f, “string”print >>f, “string”
– print “a”, “b”print “a”, “b”
– print “string”,print “string”,
● Python 3Python 3– FunçãoFunção
– print(“string”, file = f)print(“string”, file = f)
– print(“a”, “b”, sep=“ ”)print(“a”, “b”, sep=“ ”)
– print(“string”, end=“ ”)print(“string”, end=“ ”)
● Solução (parcial) imediataSolução (parcial) imediata– from __future__ import print_functionfrom __future__ import print_function
Almost there...Almost there...
![Page 28: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/28.jpg)
28
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Unicode!!!Unicode!!!
● Nomes de variável em unicodeNomes de variável em unicode● *.py em UTF-8 (Python 3)*.py em UTF-8 (Python 3)
– No Python 2, em uma das 2 primeiras linhas:No Python 2, em uma das 2 primeiras linhas:
# coding: utf-8# coding: utf-8
● Pensar no unicode (str do Python 3) como um objeto.Pensar no unicode (str do Python 3) como um objeto.– Encode: codifica o unicode para uma string de bytesEncode: codifica o unicode para uma string de bytes
– Decode: dos bytes, obtém o unicodeDecode: dos bytes, obtém o unicode
● The Absolute Minimum Every Software Developer The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)and Character Sets (No Excuses!)
http://www.joelonsoftware.com/articles/Unicode.htmlhttp://www.joelonsoftware.com/articles/Unicode.html
![Page 29: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/29.jpg)
29
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Unicode!!!Unicode!!!
● u“texto” (Python 3.3 e 2.x)u“texto” (Python 3.3 e 2.x)● from __future__ import unicode_literalsfrom __future__ import unicode_literals
– Funciona no Python 3.2Funciona no Python 3.2
● Conversão manual (testar tipo)Conversão manual (testar tipo)
● Provavelmente o aspecto mais difícil durante a Provavelmente o aspecto mais difícil durante a compatibilizaçãocompatibilização– os.urandom no simplekv (flask-kvsession)os.urandom no simplekv (flask-kvsession)
![Page 30: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/30.jpg)
30
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Itertools e functoolsItertools e functools
● reducereduce– from functools import reducefrom functools import reduce
● zip, map, filter (e zip_longest)zip, map, filter (e zip_longest)– Python 2: ListasPython 2: Listas
– Python 3: Comportamento tardio (lazy), similar ao Python 3: Comportamento tardio (lazy), similar ao izip, imap, ifilter do itertools do Python 2izip, imap, ifilter do itertools do Python 2
● ItertoolsItertools– Não possui mais izip, imap, ifilter, izip_longestNão possui mais izip, imap, ifilter, izip_longest
– Novo accumulateNovo accumulate
![Page 31: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/31.jpg)
31
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
DivisãoDivisão
● 1 / 21 / 2– 0 no Python 2 (int)0 no Python 2 (int)
– 0.5 no Python 3 (float)0.5 no Python 3 (float)
● 1 // 21 // 2– 0 no Python 2 (int)0 no Python 2 (int)
– 0 no Python 3 (int)0 no Python 3 (int)
● Solução imediataSolução imediata– from __future__ import divisionfrom __future__ import division
![Page 32: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/32.jpg)
32
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Parte 4Parte 4Diferenças inusitadasDiferenças inusitadas
![Page 33: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/33.jpg)
33
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Arredondamento de ponto Arredondamento de ponto flutuanteflutuante
In [1]: round(.5)Out[1]: 1.0
In [2]: round(-.5)Out[2]: -1.0
In [1]: round(.5)Out[1]: 1.0
In [2]: round(-.5)Out[2]: -1.0
● Python 2Python 2 ● Python 3Python 3
● Solução? Depende do comportamento desejadoSolução? Depende do comportamento desejado– audiolazy.rintaudiolazy.rint
In [1]: round(.5)Out[1]: 0
In [2]: round(-.5)Out[2]: 0
In [1]: round(.5)Out[1]: 0
In [2]: round(-.5)Out[2]: 0
![Page 34: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/34.jpg)
34
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Namespace da classeNamespace da classe
● Python 2Python 2– Funciona okFunciona ok
● Python 3Python 3– NameError: global NameError: global
name 'data' is not name 'data' is not defineddefined
class A(object): data = [1, 2, 3] data_powers = [[x ** n for x in data] for n in range(3)]
class A(object): data = [1, 2, 3] data_powers = [[x ** n for x in data] for n in range(3)]
● CompatibilizarCompatibilizar
– data_powers = (lambda data: […])(data)data_powers = (lambda data: […])(data)– Deixar fora da classeDeixar fora da classe
– Colocar no __init__ ou no __new__ da metaclasseColocar no __init__ ou no __new__ da metaclasse
![Page 35: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/35.jpg)
35
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Parte 4Parte 4FinalizaçãoFinalização
![Page 36: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/36.jpg)
36
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Python 2.6 e 2.7Python 2.6 e 2.7
● Apenas no Python 2.7Apenas no Python 2.7– Dict comprehensionDict comprehension
● dict((k, v) for k, v in my_iterable)dict((k, v) for k, v in my_iterable)
– Set comprehensionSet comprehension● set(el for el in my_iterable)set(el for el in my_iterable)
– collections.OrderedDictcollections.OrderedDict● pip install ordereddictpip install ordereddict
● Outros features do Python 3.1 (backported)Outros features do Python 3.1 (backported)
http://docs.python.org/dev/whatsnew/2.7.htmlhttp://docs.python.org/dev/whatsnew/2.7.html
Comprehension com {}:
Comprehension com {}:
apenas Python 2.7, 3.1 e
apenas Python 2.7, 3.1 e mais recentes
mais recentes
![Page 37: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/37.jpg)
37
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
sixsix
● Pacote de compatibilizaçãoPacote de compatibilização– Funções para iterar em dicionáriosFunções para iterar em dicionários– Constantes com tipos para uso com isinstanceConstantes com tipos para uso com isinstance– callable (Ausente no Python 3 até o 3.1)callable (Ausente no Python 3 até o 3.1)– Preocupação com Python 2.4 e 2.5Preocupação com Python 2.4 e 2.5
● Avaliação tardiaAvaliação tardia– Não importa nada à toaNão importa nada à toa– Engana análise para auto-completeEngana análise para auto-complete
● Metaclasse (mantém um nível hierárquico adicional)Metaclasse (mantém um nível hierárquico adicional)– class A(with_metaclass(Meta, Base)) # Apenas uma baseclass A(with_metaclass(Meta, Base)) # Apenas uma base– Neste caso, a audiolazy.meta é mais geralNeste caso, a audiolazy.meta é mais geral
Utilizado pelo
Utilizado pelo MatPlotLibMatPlotLib
![Page 38: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/38.jpg)
38
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
ninenine● Favorece o Python 3Favorece o Python 3● Para código a partir do Python 2.6Para código a partir do Python 2.6● Boilerplate sugeridoBoilerplate sugerido
# -*- coding: utf-8 -*-from __future__ import (absolute_import, division, print_function, unicode_literals)from nine import (IS_PYTHON2, str, basestring, native_str, chr, integer_types, class_types, range, range_list, reraise, iterkeys, itervalues, iteritems, map, zip, filter, input, implements_iterator, implements_to_string, implements_repr, nine, nimport)
# -*- coding: utf-8 -*-from __future__ import (absolute_import, division, print_function, unicode_literals)from nine import (IS_PYTHON2, str, basestring, native_str, chr, integer_types, class_types, range, range_list, reraise, iterkeys, itervalues, iteritems, map, zip, filter, input, implements_iterator, implements_to_string, implements_repr, nine, nimport)
![Page 39: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/39.jpg)
39
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Alternativas à compatibilizaçãoAlternativas à compatibilização
● Conversão automáticaConversão automática– Distribute com 2to3 ou 3to2Distribute com 2to3 ou 3to2
● Conversão manualConversão manual– Branches para cada versãoBranches para cada versão
● IncompatibilidadeIncompatibilidade– Código [parcialmente] restrito a versões específicasCódigo [parcialmente] restrito a versões específicas
● ““Imports” localizados apenas onde necessárioImports” localizados apenas onde necessário
![Page 40: (2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3](https://reader033.vdocuments.pub/reader033/viewer/2022042817/559e5c5c1a28abdc7f8b468e/html5/thumbnails/40.jpg)
40
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 32013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini
Brasília – DFBrasília – DFCentro de Convenções Centro de Convenções
Ulysses GuimarãesUlysses Guimarães
Obrigado!Obrigado!>>> from audiolazy import lazy_compat as compat>>> dir(compat)['INT_TYPES', 'NEXT_NAME', 'PYTHON2', 'SOME_GEN_TYPES', 'STR_TYPES', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', 'builtins', 'im_func', 'it', 'iteritems', 'itervalues', 'meta', 'orange', 'sys', 'types', 'xfilter', 'xmap', 'xrange', 'xzip', 'xzip_longest']
>>> from audiolazy import lazy_compat as compat>>> dir(compat)['INT_TYPES', 'NEXT_NAME', 'PYTHON2', 'SOME_GEN_TYPES', 'STR_TYPES', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', 'builtins', 'im_func', 'it', 'iteritems', 'itervalues', 'meta', 'orange', 'sys', 'types', 'xfilter', 'xmap', 'xrange', 'xzip', 'xzip_longest']
Perguntas?Perguntas?
https://github.com/danilobellini/audiolazyhttps://github.com/danilobellini/[email protected]@danilobellini
danilo [dot] bellini [at] gmail [dot] comdanilo [dot] bellini [at] gmail [dot] com