Luciano Ramalho  luciano@ramalho.orgoutubro/2012                                                                ac to     ...
Conceito: “objeto”• Um componente de software  que inclui dados (campos) e  comportamentos (métodos)• Em geral, os atribut...
Terminologiapythonica• Objetos possuem atributos• Os atributos de um objeto  podem ser: •  métodos                 funções...
Exemplo: um objeto dict>>> d = {AM:Manaus, PE:Recife, PR: Curitiba}>>> d.keys()[PR, AM, PE]>>> d.get(PE)Recife>>> d.pop(PR...
Exemplo: um objeto dict   • dir revela atributos de um dict    • atributos de dados e métodos>>> dir(d)[__class__, __cmp__...
Exemplo: um objeto dict                            • Sobrecarga de operadores:                             • [ ]: __getite...
Exemplo: um objeto dict    • Atributos de dados: __class__, __doc__ >>> d.__class__ <type dict> >>> type(d) <type dict> >>...
Exemplo: outro dict>>> d = dict()>>> d.keys()[]                                       • d = dict()>>> d.get(bla)>>> print ...
Exercício: construir e controlar Tkinter.Labelimport Tkinterrelogio = Tkinter.Label()relogio.pack()relogio[font] = Helveti...
Tudo é um objeto• Não existem “tipos primitivos” como em Java • desde Python 2.2, dezembro de 2001          >>> 5 + 3     ...
Tipos embutidos• Implementados em C, por eficiência• Comportamentos fixos• Texto: str, unicode• Números: int, long, float, co...
Funções são objetos  >>> def fatorial(n):  ...     devolve n!  ...     return 1 if n < 2 else n * fatorial(n-1)  ...  >>> ...
Funções são objetos>>> fatorial.__code__.co_code|x00x00dx01x00jx00x00ox05x00x01dx02x00Sx01|x00x00tx00x00|x00x00dx02x00x18x...
Tipagem forte• O tipo de um objeto nunca muda• Raramente Python faz conversão automática de  tipos    >>> a = 10    >>> b ...
Tipagem dinâmica:variáveis não têm tipo>>> def dobro(x):...      return x * 2...>>> dobro(7)14>>> dobro(7.1)14.2>>> dobro(...
Orientação a objetos:a origem• Linguagem Simula 1967 • Noruega: Ole-Johan Dahl e Kristen Nygaard • objetos, classes, sub-c...
Orientação a objetos:evolução• Smalltalk 1980 • EUA, Xerox PARC (Palo Alto Research Center):    Alan Kay, Dan Ingalls, Ade...
Smalltalk 1980
Squeak: Smalltalk livre
Duck typing• “Se voa como um pato, nada como um pato e  grasna como um pato, é um pato.”• Tipagem dinâmica permite duck ty...
Tipagem forte x fraca                                   JavaScript                                                     (EC...
Tipagem forte x fraca,dinâmica x estática• Tipagem forte x fraca refere-se a conversão  automática de valores de tipos dif...
Tipagem em linguagens  Smalltalk   dinâmica   forte    Python    dinâmica   forte      Ruby    dinâmica   forte  C (K&R)  ...
Conversões automáticas• Python faz algumas (poucas) conversões  automáticas entre tipos: • Promoção de int para float • Pro...
Tipos são classes• Para criar um novo tipo de objeto, crie uma classe• A função type devolve a classe de um objeto  >>> cl...
Conceito: “classe”• Uma categoria, ou tipo, de objeto • Uma idéia abstrata, uma forma platônica• Exemplo: classe “Cão”: • ...
Exemplar de cão:instância da classe Cao      >>> rex = Cao()   instanciação
instanciação   >>> rex = Cao(Rex)                                                 >>> rex Classe Cao                      ...
Como atributos sãoacessados• Ao buscar o.a (atributo a do objeto o da classe C),  o interpretador Python faz o seguinte:• ...
Classe Cao em Pythonclass Mamifero(object):    """lição de casa: implementar"""                                           ...
>>> rex = Cao(Rex)                                                         >>> rex Classe Cao                             ...
Classe Cao em Pythonclass Mamifero(object):    """lição de casa: implementar"""             •   atributos de dados na     ...
Mamifero: superclasse de Caoclass Mamifero(object):                       UML                                             ...
Subclasses de Cao      • Continuação         de cao.pyclass Pequines(Cao):    nervoso = True    class Mastiff(Cao):    def...
Subclasses                    >>> sansao = SaoBernardo(Sansao) de Cao                        >>> sansao.servir()          ...
Subclasses de Cao      • Continuação         de cao.pyclass Pequines(Cao):    nervoso = True    class Mastiff(Cao):    def...
Interface                • Interface é um conceito essencial em OO                 • não depende de uma palavra reservada ...
Interfaces e protocolos• Em SmallTalk, as interfaces eram chamadas de  “protocolos”. • Não há verificação de interfaces na ...
Interfaces em Python• Conceitualmente, sempre existiram como  protocolos• Não havia maneira formal de especificar interface...
Exemplo: tômbola• Sortear um a um  todos os itens de  uma coleção finita,  sem repetir• A mesma lógica é  usada em sistemas...
Interface da tômbola• Carregar itens• Misturar itens• Sortear um item• Indicar se há mais  itens
Projeto da tômbola• UML: diagrama de classe
TDD: Test Driven Design• Metodologia de desenvolvimento iterativa na qual,  para cada funcionalidade nova, um teste é cria...
Doctests• Um dos módulos para fazer testes automatizados  na biblioteca padrão de Python • o outro módulo é o unittest, da...
Coding Dojo• Implementação da classe Tombola, com testes  feitos em Doctest
Implementação da tômbola                      # coding: utf-8                      import random                      clas...
Iteração em C e Python#include <stdio.h>int main(int argc, char *argv[]) {    int i;    for(i = 0; i < argc; i++)        p...
Iteração em Javaclass Argumentos {    public static void main(String[] args) {        for (int i=0; i < args.length; i++) ...
ano:Iteração em Java ≥1.5                          2004 • Enhanced for (for melhorado)class Argumentos2 {    public static...
ano:Iteração em Java ≥1.5                    2004 • Enhanced for (for melhorado)class Argumentos2 {    public static void ...
Exemplos de iteração• Iteração em Python não se limita a tipos primitivos• Exemplos • string • arquivo • Django QuerySet •...
List comprehensionList comprehensions          ●   Compreensão de lista ou abrangência                             ●   Exe...
Set & dict comprehensions• Expressões que consomem iteráveis e  produzem sets ou dicts >>> s = abracadabra >>> {c for c in...
Em Python o comando foritera sobre... “iteráveis”• Definicão preliminar informal: • “iterável” = que pode ser iterado • ass...
Tipos iteráveis embutidos  • basestring   • frozenset   • str         • list   • unicode     • set  • dict         • tuple...
Funções embutidas queconsomem iteráveis• all       • max• any       • min• filter     • reduce• iter      • sorted• len    ...
Operações com iteráveis                                       >>>   a, b, c = XYZ  • Desempacotamento                   >>...
Em Python, um iterável é...• Um objeto a partir do qual a função iter  consegue obter um iterador.• A chamada iter(x): • i...
Protocolo de sequência >>> t = Trem(4) >>> len(t) 4                       __len__ >>> t[0] vagao #1 >>> t[3]              ...
Protocolo  de sequência • implementação “informal” da interfaceclass Trem(object):    def __init__(self, num_vagoes):     ...
Tômbola como sequência• Permitir contagem  de itens• Permitir acesso  direto a cada item  pela ordem em que  foi colocadoS...
Interface  Sequence  • collections.Sequencefrom collections import Sequenceclass Trem(Sequence):    def __init__(self, num...
Herança de Sequence>>> t = Trem(4)>>> vagao #2 in tTrue>>> vagao #5 in tFalse>>> for i in reversed(t): print i...vagao #4v...
InterfaceIterable• Iterable provê um método  __iter__• O método __iter__ devolve  uma instância de Iterator               ...
Iterator é...• um padrão de projeto                         Design Patterns                         Gamma, Helm, Johnson &...
Head FirstDesign PatternsPosterOReilly,ISBN 0-596-10214-3                     @ramalhoorg
O padrãoIterator permiteacessar os itensde uma coleçãosequencialmente,isolando o clienteda implementaçãoda coleção.Head Fi...
Trem                      class Trem(object):                          def __init__(self, num_vagoes):                    ...
Tômbola iterável• Permitir iteração  sobre tômbola em  um laço for,  devolvendo os itens  em uma ordem  sorteada  Agora o ...
Recapitulando: iterável é...• Um objeto a partir do qual a função iter  consegue obter um iterador.• A chamada iter(x):   ...
Iteração em C (exemplo 2) #include <stdio.h> int main(int argc, char *argv[]) {     int i;     for(i = 0; i < argc; i++)  ...
Iteração em Python (ex. 2) import sys for i, arg in enumerate(sys.argv):     print i, :, arg              $   python args2...
Iterator x generator• Gerador é uma generalização do iterador• Por definição, um objeto iterador produz itens  iterando sob...
Função               >>> def g123():geradora                     ...     yield 1                     ...     yield 2      ...
Trem c/ função geradora                      class Trem(object):                          def __init__(self, num_vagoes): ...
class Trem(object):Iterador        def __init__(self, num_vagoes):                    self.num_vagoes = num_vagoes        ...
Expressãogeradora             >>> g = (n for n in [1, 2, 3])                     >>> for i in g: print i                  ...
Trem c/ expressão geradora                      class Trem(object):                          def __init__(self, num_vagoes...
Construtores embutidosque consomem eproduzem iteráveis• dict        • reversed• enumerate   • set• frozenset   • tuple• li...
Módulo itertools• geradores (potencialmente) infinitos • count(), cycle(), repeat()• geradores que combinam vários iterávei...
Exemplo prático comfunções geradoras• Funções geradoras para desacoplar laços de  leitura e escrita em uma ferramenta para...
Laço principal escrevearquivo JSON                         @ramalhoorg
Um outro laço lê osregistros a converter                        @ramalhoorg
Implementação possível:o mesmo laço lê e grava                      @ramalhoorg
Mas e a lógica para leroutro formato?                          @ramalhoorg
Funçõesdo script • iterMstRecords* • iterIsoRecords* • writeJsonArray • main	      * funções geradoras                    ...
Função main:leitura dosargumentos               @ramalhoorg
Função main: seleçãodo formato escolha dadepende geradora               de leitura                          função        ...
writeJsonArray:escreverregistrosem JSON                  @ramalhoorg
writeJsonArray:itera sobre umas dasfunções geradoras                       @ramalhoorg
iterIsoRecords:ler registros     função geradora!de arquivoISO-2709                            @ramalhoorg
iterIsoRecords                        cria um novo dict                        a cada iteração                 produz (yie...
iterMstRecords:   função geradora!ler registrosde arquivoISIS .MST                             @ramalhoorg
iterMstRecordsiterIsoRecords                    cria um novo dict                    a cada iteração             produz (y...
Geradores na prática                       @ramalhoorg
Geradores na prática                       @ramalhoorg
Geradores na prática                       @ramalhoorg
Oficinas Turing:    computação para programadores•   Próximos lançamentos:    •   4ª turma de Python para quem sabe Python ...
Próximos SlideShares
Carregando em…5
×

Objetos Pythonicos - compacto

2.278 visualizações

Publicada em

versão compacta do curso Objetos Pythonicos de Oficinas Turing

Publicada em: Tecnologia
0 comentários
5 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
2.278
No SlideShare
0
A partir de incorporações
0
Número de incorporações
6
Ações
Compartilhamentos
0
Downloads
79
Comentários
0
Gostaram
5
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Objetos Pythonicos - compacto

  1. 1. Luciano Ramalho luciano@ramalho.orgoutubro/2012 ac to mp Objetos Pythonicos co Orientação a objetos e padrões de projeto em Python
  2. 2. Conceito: “objeto”• Um componente de software que inclui dados (campos) e comportamentos (métodos)• Em geral, os atributos são manipulados pelos métodos do próprio objeto (encapsulamento) Figuras: bycicle (bicicleta), The Java Tutorial http://docs.oracle.com/javase/tutorial/java/concepts/object.html
  3. 3. Terminologiapythonica• Objetos possuem atributos• Os atributos de um objeto podem ser: • métodos funções associadas • atributos de dados “campos” Figuras: bycicle (bicicleta), The Java Tutorial http://docs.oracle.com/javase/tutorial/java/concepts/object.html
  4. 4. Exemplo: um objeto dict>>> d = {AM:Manaus, PE:Recife, PR: Curitiba}>>> d.keys()[PR, AM, PE]>>> d.get(PE)Recife>>> d.pop(PR)Curitiba>>> d{AM: Manaus, PE: Recife}>>> len(d)2>>> d.__len__()2 • Métodos: keys, get, pop, __len__ etc.
  5. 5. Exemplo: um objeto dict • dir revela atributos de um dict • atributos de dados e métodos>>> dir(d)[__class__, __cmp__, __contains__, __delattr__, __delitem__,__doc__, __eq__, __format__, __ge__, __getattribute__,__getitem__, __gt__, __hash__, __init__, __iter__, __le__,__len__, __lt__, __ne__, __new__, __reduce__,__reduce_ex__, __repr__, __setattr__, __setitem__,__sizeof__, __str__, __subclasshook__, clear, copy,fromkeys, get, has_key, items, iteritems, iterkeys,itervalues, keys, pop, popitem, setdefault, update,values]
  6. 6. Exemplo: um objeto dict • Sobrecarga de operadores: • [ ]: __getitem__, __setitem__>>> d{AM: Manaus, PE: Recife}>>> d[AM]Manaus>>> d.__getitem__(AM)Manaus>>> d[MG] = Belo Horizonte>>> d.__setitem__(RJ, Rio de Janeiro)>>> d{MG: Belo Horizonte, AM: Manaus, RJ: Rio de Janeiro, PE: Recife}
  7. 7. Exemplo: um objeto dict • Atributos de dados: __class__, __doc__ >>> d.__class__ <type dict> >>> type(d) <type dict> >>> print d.__doc__ dict() -> new empty dictionary. dict(mapping) -> new dictionary initialized from a mapping objects (key, value) pairs. dict(seq) -> new dictionary initialized as if via: d = {} for k, v in seq: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
  8. 8. Exemplo: outro dict>>> d = dict()>>> d.keys()[] • d = dict()>>> d.get(bla)>>> print d.get(bla) é o mesmo queNone d = {}>>> d.get(spam)>>> print d.get(spam)None>>> d.pop(ovos)Traceback (most recent call last): File "<stdin>", line 1, in <module>KeyError: ovos>>> d{}>>> len(d)0>>> d.__len__()0
  9. 9. Exercício: construir e controlar Tkinter.Labelimport Tkinterrelogio = Tkinter.Label()relogio.pack()relogio[font] = Helvetica 120 boldrelogio[text] = strftime(%H:%M:%S)from time import strftimedef tic():    relogio[text] = strftime(%H:%M:%S)    def tac(): Note: no Tkinter, atributos    relogio.after(100, tictac) de dados são acessados via [ ]:tac()relogio.mainloop() __getitem__ __setitem__
  10. 10. Tudo é um objeto• Não existem “tipos primitivos” como em Java • desde Python 2.2, dezembro de 2001 >>> 5 + 3 8 >>> 5 .__add__(3) 8 >>> type(5) <type int>
  11. 11. Tipos embutidos• Implementados em C, por eficiência• Comportamentos fixos• Texto: str, unicode• Números: int, long, float, complex, bool• Coleções: list, tuple, dict, set, frozenset• etc.
  12. 12. Funções são objetos >>> def fatorial(n): ... devolve n! ... return 1 if n < 2 else n * fatorial(n-1) ... >>> fatorial(5) 120 >>> fat = fatorial >>> fat <function fatorial at 0x1004b5f50> >>> fat(42) 1405006117752879898543142606244511569936384000000000L >>> fatorial.__doc__ devolve n! >>> fatorial.__name__ fatorial >>> fatorial.__code__ <code object fatorial at 0x1004b84e0, file "<stdin>", line 1> >>> fatorial.__code__.co_varnames (n,)
  13. 13. Funções são objetos>>> fatorial.__code__.co_code|x00x00dx01x00jx00x00ox05x00x01dx02x00Sx01|x00x00tx00x00|x00x00dx02x00x18x83x01x00x14S>>> from dis import dis>>> dis(fatorial.__code__.co_code) 0 LOAD_FAST 0 (0) 3 LOAD_CONST 1 (1) 6 COMPARE_OP 0 (<) Bytecode da 9 JUMP_IF_FALSE 5 (to 17) 12 POP_TOP 13 LOAD_CONST 2 (2) >> 16 RETURN_VALUE 17 POP_TOP função fatorial 18 LOAD_FAST 0 (0) 21 LOAD_GLOBAL 0 (0) 24 LOAD_FAST 0 (0) 27 LOAD_CONST 2 (2) 30 BINARY_SUBTRACT 31 CALL_FUNCTION 1 34 BINARY_MULTIPLY 35 RETURN_VALUE>>>
  14. 14. Tipagem forte• O tipo de um objeto nunca muda• Raramente Python faz conversão automática de tipos >>> a = 10 >>> b = 9 >>> a + b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: int and str >>> a + int(b) 19 >>> str(a) + b 109 >>> 77 * None Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for *: int and NoneType >>>
  15. 15. Tipagem dinâmica:variáveis não têm tipo>>> def dobro(x):... return x * 2...>>> dobro(7)14>>> dobro(7.1)14.2>>> dobro(bom)bombom>>> dobro([10, 20, 30])[10, 20, 30, 10, 20, 30]>>> dobro(None)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in dobroTypeError: unsupported operand type(s) for *: NoneType and int
  16. 16. Orientação a objetos:a origem• Linguagem Simula 1967 • Noruega: Ole-Johan Dahl e Kristen Nygaard • objetos, classes, sub-classes • métodos virtuais (funções associadas a objetos específicos somente em tempo de execução, e não na compilação)
  17. 17. Orientação a objetos:evolução• Smalltalk 1980 • EUA, Xerox PARC (Palo Alto Research Center): Alan Kay, Dan Ingalls, Adele Goldberg et. al.• Terminologia: • “Object oriented programming” • “message passing” (invocação de métodos), “late binding” (métodos virtuais)
  18. 18. Smalltalk 1980
  19. 19. Squeak: Smalltalk livre
  20. 20. Duck typing• “Se voa como um pato, nada como um pato e grasna como um pato, é um pato.”• Tipagem dinâmica permite duck typing (tipagem pato) estilo de programação que evita verificar os tipos dos objetos, mas apenas seus métodos• No exemplo anterior, a função dobro funciona com qualquer objeto x que consiga fazer x * 2 • x implementa o método __mult__(n), para n inteiro
  21. 21. Tipagem forte x fraca JavaScript (ECMAScript 5)• Tipagem forte x fraca refere-se a em Node.js 0.6 conversão automática de valores de tipos diferente.• Linguagens de tipagem fraca são muito > 10 + 9 109 > 10 + 9 * 1 liberais na mistura entre tipos, e isso é 19 uma fonte de bugs. > 10 + 9 * 1 109 Veja alguns resultados estranhos obtidos > 0 == 0 com JavaScript, que tem tipagem fraca. true > 0 == Em Python as três expressões acima geram true TypeError, e as três últimas resultam False. > 0 == Python tem tipagem forte. false
  22. 22. Tipagem forte x fraca,dinâmica x estática• Tipagem forte x fraca refere-se a conversão automática de valores de tipos diferentes• Tipagem dinâmica x estática refere-se à declaração dos tipos das variáveis, parâmetros formais e valores devolvidos pelas funções • Linguagens de tipagem estática exigem a declaração dos tipos, ou usam inferência de tipos para garantir que uma variável será associada a somente a valores de um tipo
  23. 23. Tipagem em linguagens Smalltalk dinâmica forte Python dinâmica forte Ruby dinâmica forte C (K&R) estática fraca C (ANSI) estática forte Java estática forte C# estática forte combinação JavaScript PHP dinâmica dinâmica fraca fraca } perigosa: bugs sorrateiros
  24. 24. Conversões automáticas• Python faz algumas (poucas) conversões automáticas entre tipos: • Promoção de int para float • Promoção de str para unicode • assume o encoding padrão: ASCII por default >>> 6 * 7.0 42.0 >>> Spam, + ueggs uSpam, eggs >>>
  25. 25. Tipos são classes• Para criar um novo tipo de objeto, crie uma classe• A função type devolve a classe de um objeto >>> class Mamifero(object): ... pass ... >>> kingkong = Mamifero() >>> type(kingkong) <class __main__.Mamifero> >>> ClasseDoKingKong = type(kingkong) >>> dumbo = ClasseDoKingKong() >>> dumbo <__main__.Mamifero object at 0x10045dcd0> >>> type(dumbo) <class __main__.Mamifero>
  26. 26. Conceito: “classe”• Uma categoria, ou tipo, de objeto • Uma idéia abstrata, uma forma platônica• Exemplo: classe “Cão”: • Eu digo: “Ontem eu comprei um cão” • Você não sabe exatamente qual cão, mas sabe: • é um mamífero, quadrúpede, carnívoro • pode ser domesticado (normalmente) • cabe em um automóvel
  27. 27. Exemplar de cão:instância da classe Cao >>> rex = Cao() instanciação
  28. 28. instanciação >>> rex = Cao(Rex) >>> rex Classe Cao Cao(Rex) >>> print rex Rex >>> rex.qt_patasclass Mamifero(object): 4    """lição de casa: implementar""" >>> rex.latir() Rex: Au!class Cao(Mamifero): >>> rex.latir(2)    qt_patas = 4    carnivoro = True Rex: Au! Au!    nervoso = False >>> rex.nervoso = True    def __init__(self, nome): >>> rex.latir(3)        self.nome = nome Rex: Au! Au! Au! Au! Au! Au!    def latir(self, vezes=1):        # quando nervoso, late o dobro        vezes = vezes + (self.nervoso * vezes)        print self.nome + : + Au! * vezes    def __str__(self):        return self.nome    def __repr__(self):        return Cao({0!r}).format(self.nome) oopy/exemplos/cao.py
  29. 29. Como atributos sãoacessados• Ao buscar o.a (atributo a do objeto o da classe C), o interpretador Python faz o seguinte:• 1) acessa atributo a da instancia o; caso não exista...• 2) acessa atributo a da classe C de o (type(o) ou o.__class__); caso nao exista...• 3) busca o atributo a nas superclasses de C, conforme a MRO (method resolution order)
  30. 30. Classe Cao em Pythonclass Mamifero(object):    """lição de casa: implementar""" • __init__ é oclass Cao(Mamifero):    qt_patas = 4 construtor, ou melhor,    carnivoro = True    nervoso = False o inicializador •    def __init__(self, nome):        self.nome = nome    def latir(self, vezes=1): self é o 1º parâmetro        # quando nervoso, late o dobro formal em todos os        vezes = vezes + (self.nervoso * vezes)        print self.nome + : + Au! * vezes métodos de instância    def __str__(self):        return self.nome    def __repr__(self):        return Cao({0!r}).format(self.nome) oopy/exemplos/cao.py
  31. 31. >>> rex = Cao(Rex) >>> rex Classe Cao Cao(Rex) >>> print rex Rex >>> rex.qt_patasclass Mamifero(object): 4    """lição de casa: implementar""" >>> rex.latir() Rex: Au!class Cao(Mamifero): invocação >>> rex.latir(2)    qt_patas = 4 Rex: Au! Au!    carnivoro = True    nervoso = False •    def __init__(self, nome):        self.nome = nome    def latir(self, vezes=1): na invocação do        # quando nervoso, late o dobro método, a instância        vezes = vezes + (self.nervoso * vezes)        print self.nome + : + Au! * vezes é passada    def __str__(self):        return self.nome automaticamente    def __repr__(self):        return Cao({0!r}).format(self.nome) na posição do self oopy/exemplos/cao.py
  32. 32. Classe Cao em Pythonclass Mamifero(object):    """lição de casa: implementar""" • atributos de dados na classe funcionamclass Cao(Mamifero):    qt_patas = 4 como valores default    carnivoro = True    nervoso = False para os atributos das    def __init__(self, nome):        self.nome = nome instâncas •    def latir(self, vezes=1):        # quando nervoso, late o dobro        vezes = vezes + (self.nervoso * vezes) atributos da instância        print self.nome + : + Au! * vezes só podem ser    def __str__(self):        return self.nome acessados via self    def __repr__(self):        return Cao({0!r}).format(self.nome) oopy/exemplos/cao.py
  33. 33. Mamifero: superclasse de Caoclass Mamifero(object): UML diagrama de classe    """lição de casa: implementar""" especializaçãoclass Cao(Mamifero): generalização    qt_patas = 4    carnivoro = True    nervoso = False    def __init__(self, nome):        self.nome = nome    def latir(self, vezes=1):        # quando nervoso, late o dobro        vezes = vezes + (self.nervoso * vezes)        print self.nome + : + Au! * vezes    def __str__(self):        return self.nome    def __repr__(self):        return Cao({0!r}).format(self.nome) oopy/exemplos/cao.py
  34. 34. Subclasses de Cao • Continuação de cao.pyclass Pequines(Cao):    nervoso = True    class Mastiff(Cao):    def latir(self, vezes=1):        # o mastiff não muda seu latido quando nervoso        print self.nome + : + Wuff! * vezes        class SaoBernardo(Cao):    def __init__(self, nome):        Cao.__init__(self, nome)        self.doses = 10 Diz a lenda que o cão    def servir(self): São Bernardo leva um        if self.doses == 0: pequeno barril de conhaque            raise ValueError(Acabou o conhaque!)        self.doses -= 1 para resgatar viajantes        msg = {0} serve o conhaque (restam {1} doses) perdidos na neve.        print msg.format(self.nome, self.doses)
  35. 35. Subclasses >>> sansao = SaoBernardo(Sansao) de Cao >>> sansao.servir() Sansao serve o conhaque (restam 9 doses) >>> sansao.doses = 1 >>> sansao.servir() Sansao serve o conhaque (restam 0 doses) >>> sansao.servir()class Pequines(Cao): Traceback (most recent call last):    nervoso = True ...    class Mastiff(Cao): ValueError: Acabou o conhaque!    def latir(self, vezes=1):        # o mastiff não muda seu latido quando nervoso        print self.nome + : + Wuff! * vezes        class SaoBernardo(Cao):    def __init__(self, nome):        Cao.__init__(self, nome)        self.doses = 10    def servir(self):        if self.doses == 0:            raise ValueError(Acabou o conhaque!)        self.doses -= 1        msg = {0} serve o conhaque (restam {1} doses)        print msg.format(self.nome, self.doses)
  36. 36. Subclasses de Cao • Continuação de cao.pyclass Pequines(Cao):    nervoso = True    class Mastiff(Cao):    def latir(self, vezes=1):        # o mastiff não muda seu latido quando nervoso        print self.nome + : + Wuff! * vezes        class SaoBernardo(Cao):    def __init__(self, nome):        Cao.__init__(self, nome)        self.doses = 10    def servir(self):        if self.doses == 0:            raise ValueError(Acabou o conhaque!)        self.doses -= 1        msg = {0} serve o conhaque (restam {1} doses)        print msg.format(self.nome, self.doses)
  37. 37. Interface • Interface é um conceito essencial em OO • não depende de uma palavra reservada A interface fornece uma separação entre a implementação de uma abstração e seus clientes. Ela limita os detalhes de implementação que os clientes podem ver. Também especifica a funcionalidade que as implementações devem prover.P. S. Canning, W. R. Cook, W. L. Hill, and W. G. Olthoff. 1989. Interfaces for strongly-typed object-oriented programming. In Conference proceedings on Object-oriented programming systems,languages and applications (OOPSLA 89). ACM, New York, NY, USA, 457-467.DOI=10.1145/74877.74924 http://doi.acm.org/10.1145/74877.74924
  38. 38. Interfaces e protocolos• Em SmallTalk, as interfaces eram chamadas de “protocolos”. • Não há verificação de interfaces na linguagem, mas algumas IDEs (“browsers”) permitem agrupar os métodos por protocolo para facilitar a leitura• Um protocolo é uma interface informal, não declarada porém implementada por métodos concretos
  39. 39. Interfaces em Python• Conceitualmente, sempre existiram como protocolos• Não havia maneira formal de especificar interfaces em Python até a versão 2.5 • usava-se termos como “uma sequência” ou “a file-like object”• Agora temos ABC (Abstract Base Class) • com herança múltipla, como em C++
  40. 40. Exemplo: tômbola• Sortear um a um todos os itens de uma coleção finita, sem repetir• A mesma lógica é usada em sistemas para gerenciar banners online
  41. 41. Interface da tômbola• Carregar itens• Misturar itens• Sortear um item• Indicar se há mais itens
  42. 42. Projeto da tômbola• UML: diagrama de classe
  43. 43. TDD: Test Driven Design• Metodologia de desenvolvimento iterativa na qual, para cada funcionalidade nova, um teste é criado antes do código a ser implementado• Esta inversão ajuda o programador a desenvolver com disciplina apenas uma funcionalidade de cada vez, mantendo o foco no teste que precisa passar• Cada iteração de teste/implementação deve ser pequena e simples: “baby steps” (passinhos de bebê)
  44. 44. Doctests• Um dos módulos para fazer testes automatizados na biblioteca padrão de Python • o outro módulo é o unittest, da família xUnit• Doctests foram criados para testar exemplos embutidos na documentação• Usaremos doctests para especificar exercícios• Exemplo: $ python -m doctest cao.rst oopy/exemplos/cao.rst
  45. 45. Coding Dojo• Implementação da classe Tombola, com testes feitos em Doctest
  46. 46. Implementação da tômbola # coding: utf-8 import random class Tombola(object): itens = None def carregar(self, itens): self.itens = list(itens) def carregada(self): return bool(self.itens) def misturar(self): • Python 2.2 a 2.7 random.shuffle(self.itens) def sortear(self): return self.itens.pop()
  47. 47. Iteração em C e Python#include <stdio.h>int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%sn", argv[i]); return 0;} import sys for arg in sys.argv: print arg @ramalhoorg
  48. 48. Iteração em Javaclass Argumentos { public static void main(String[] args) { for (int i=0; i < args.length; i++) System.out.println(args[i]); }} $ java Argumentos alfa bravo charlie alfa bravo charlie @ramalhoorg
  49. 49. ano:Iteração em Java ≥1.5 2004 • Enhanced for (for melhorado)class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); }} $ java Argumentos2 alfa bravo charlie alfa bravo charlie @ramalhoorg
  50. 50. ano:Iteração em Java ≥1.5 2004 • Enhanced for (for melhorado)class Argumentos2 { public static void main(String[] args) { for (String arg : args) System.out.println(arg); }} ano: import sys 1991 for arg in sys.argv: print arg @ramalhoorg
  51. 51. Exemplos de iteração• Iteração em Python não se limita a tipos primitivos• Exemplos • string • arquivo • Django QuerySet • Baralho (em: “OO em Python sem Sotaque”) https://slideshare.net/ramalho/ @ramalhoorg
  52. 52. List comprehensionList comprehensions ● Compreensão de lista ou abrangência ● Exemplo: usar todos os elementos:• Expressões que consomem L2 = [n*10 for n in L] – iteráveis e produzem listas qualquer iterável resultado: uma lista>>> s = abracadabra>>> l = [ord(c) for c in s]>>> [ord(c) for c in s][97, 98, 114, 97, 99, 97, 100, 97, 98, 114, 97] @ramalhoorg
  53. 53. Set & dict comprehensions• Expressões que consomem iteráveis e produzem sets ou dicts >>> s = abracadabra >>> {c for c in s} set([a, r, b, c, d]) >>> {c:ord(c) for c in s} {a: 97, r: 114, b: 98, c: 99, d: 100} @ramalhoorg
  54. 54. Em Python o comando foritera sobre... “iteráveis”• Definicão preliminar informal: • “iterável” = que pode ser iterado • assim como: “desmontável” = que pode ser desmontado• Iteráveis podem ser usados em outros contextos além do laço for @ramalhoorg
  55. 55. Tipos iteráveis embutidos • basestring • frozenset • str • list • unicode • set • dict • tuple • file • xrange @ramalhoorg
  56. 56. Funções embutidas queconsomem iteráveis• all • max• any • min• filter • reduce• iter • sorted• len • sum• map • zip @ramalhoorg
  57. 57. Operações com iteráveis >>> a, b, c = XYZ • Desempacotamento >>> X a de tupla >>> b Y • em atribuições >>> Z >>> c g = (n for n in [1, 2, 3]) • em chamadas de funções >>> >>> a, b, c = g a>>> def soma(a, b): 1... return a + b >>> b... 2>>> soma(1, 2) >>> c3 3>>> t = (3, 4)>>> soma(t)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: soma() takes exactly 2 arguments (1 given)>>> soma(*t) @ramalhoorg7
  58. 58. Em Python, um iterável é...• Um objeto a partir do qual a função iter consegue obter um iterador.• A chamada iter(x): • invoca x.__iter__() para obter um iterador • ou, se x.__iter__ não existe: • fabrica um iterador que acessa os itens de x sequenciamente fazendo x[0], x[1], x[2] etc. @ramalhoorg
  59. 59. Protocolo de sequência >>> t = Trem(4) >>> len(t) 4 __len__ >>> t[0] vagao #1 >>> t[3] __getitem__ vagao #4 >>> t[-1] vagao #4 >>> for vagao in t: ... print(vagao) __getitem__ vagao #1 vagao #2 vagao #3 vagao #4 @ramalhoorg
  60. 60. Protocolo de sequência • implementação “informal” da interfaceclass Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __len__(self): return self.num_vagoes def __getitem__(self, pos): indice = pos if pos >= 0 else self.num_vagoes + pos if 0 <= indice < self.num_vagoes: # indice 2 -> vagao #3 return vagao #%s % (indice+1) else: @ramalhoorg raise IndexError(vagao inexistente %s % pos)
  61. 61. Tômbola como sequência• Permitir contagem de itens• Permitir acesso direto a cada item pela ordem em que foi colocadoSim, este é um exemploforçado... mas daqui apouco melhora!
  62. 62. Interface Sequence • collections.Sequencefrom collections import Sequenceclass Trem(Sequence): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __len__(self): return self.num_vagoes def __getitem__(self, pos): indice = pos if pos >= 0 else self.num_vagoes + pos if 0 <= indice < self.num_vagoes: # indice 2 -> vagao #3 return vagao #%s % (indice+1) else: @ramalhoorg raise IndexError(vagao inexistente %s % pos)
  63. 63. Herança de Sequence>>> t = Trem(4)>>> vagao #2 in tTrue>>> vagao #5 in tFalse>>> for i in reversed(t): print i...vagao #4vagao #3 from collections import Sequevagao #2vagao #1 class Trem(Sequence):>>> t.index(vagao #2) def __init__(self, num_va1 self.num_vagoes = num>>> t.index(vagao #7) def __len__(self):Traceback (most recent call last): return self.num_vagoe ... def __getitem__(self, posValueError @ramalhoorg indice = pos if pos >
  64. 64. InterfaceIterable• Iterable provê um método __iter__• O método __iter__ devolve uma instância de Iterator @ramalhoorg
  65. 65. Iterator é...• um padrão de projeto Design Patterns Gamma, Helm, Johnson & Vlissides Addison-Wesley, ISBN 0-201-63361-2 @ramalhoorg
  66. 66. Head FirstDesign PatternsPosterOReilly,ISBN 0-596-10214-3 @ramalhoorg
  67. 67. O padrãoIterator permiteacessar os itensde uma coleçãosequencialmente,isolando o clienteda implementaçãoda coleção.Head FirstDesign PatternsPosterOReilly,ISBN 0-596-10214-3 @ramalhoorg
  68. 68. Trem class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): com return IteradorTrem(self.num_vagoes) class IteradorTrem(object): iterator def __init__(self, num_vagoes): self.atual = 0 self.ultimo_vagao = num_vagoes - 1 def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return vagao #%s % (self.atual) else: iter(t) raise StopIteration() • for vagao in t:>>> t = Trem(4)>>> for vagao in t: • invoca iter(t)... print(vagao)vagao #1 • devolve IteradorTremvagao #2vagao #3 • invoca itrem.next() até quevagao #4 ele levante StopIteration @ramalhoorg
  69. 69. Tômbola iterável• Permitir iteração sobre tômbola em um laço for, devolvendo os itens em uma ordem sorteada Agora o exemplo faz mais sentido!
  70. 70. Recapitulando: iterável é...• Um objeto a partir do qual a função iter consegue obter um iterador.• A chamada iter(x): interface Iterable • invoca x.__iter__() para obter um iterador • ou, se x.__iter__ não existe: • fabrica um iterador que acessa os itens de x sequenciamente fazendo x[0], x[1], x[2] etc. protocolo de sequência @ramalhoorg
  71. 71. Iteração em C (exemplo 2) #include <stdio.h> int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; i++) printf("%d : %sn", i, argv[i]); return 0; } $ ./args2 alfa bravo charlie 0 : ./args2 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  72. 72. Iteração em Python (ex. 2) import sys for i, arg in enumerate(sys.argv): print i, :, arg $ python args2.py alfa bravo charlie 0 : args2.py 1 : alfa 2 : bravo 3 : charlie @ramalhoorg
  73. 73. Iterator x generator• Gerador é uma generalização do iterador• Por definição, um objeto iterador produz itens iterando sobre outro objeto (alguma coleção)• Um gerador é um iterável que produz itens sem necessariamente acessar uma coleção • ele pode iterar sobre outro objeto mas também pode gerar itens por contra própria, sem qualquer dependência externa (ex. Fibonacci) @ramalhoorg
  74. 74. Função >>> def g123():geradora ... yield 1 ... yield 2 ... yield 3 ... >>> for i in g123(): print i ...• Quando invocada, 1 2 3 devolve um >>> g = g123() >>> g objeto gerador <generator object g123 at 0x10e385e10>• O objeto gerador >>> g.next() 1 >>> g.next() é um iterável 2 >>> g.next() 3 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration @ramalhoorg
  75. 75. Trem c/ função geradora class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield vagao #%s % (i+1) iter(t) • for vagao in t:>>> t = Trem(4)>>> for vagao in t: • invoca iter(t)... print(vagao)vagao #1 • devolve geradorvagao #2vagao #3 • invoca gerador.next() até quevagao #4 ele levante StopIteration @ramalhoorg
  76. 76. class Trem(object):Iterador def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self):clássico return IteradorTrem(self.num_vagoes) class IteradorTrem(object): def __init__(self, num_vagoes):12 linhas self.atual = 0 self.ultimo_vagao = num_vagoes - 1de código def next(self): if self.atual <= self.ultimo_vagao: self.atual += 1 return vagao #%s % (self.atual) else: raise StopIteration() mesma funcionalidade e desempenho!Função class Trem(object): def __init__(self, num_vagoes):geradora self.num_vagoes = num_vagoes def __iter__(self): for i in range(self.num_vagoes): yield vagao #%s % (i+1) 3 linhas
  77. 77. Expressãogeradora >>> g = (n for n in [1, 2, 3]) >>> for i in g: print i ... 1 2 3• Quando avaliada, >>> g = (n for n in [1, 2, 3]) >>> g devolve um <generator object <genexpr> at 0x109a4deb0> objeto gerador >>> g.next() 1• O objeto gerador >>> g.next() 2 é um iterável >>> g.next() 3 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration @ramalhoorg
  78. 78. Trem c/ expressão geradora class Trem(object): def __init__(self, num_vagoes): self.num_vagoes = num_vagoes def __iter__(self): return (vagao #%s % (i+1) for i in range(self.num_vagoes)) iter(t) • for vagao in t:>>> t = Trem(4)>>> for vagao in t: • invoca iter(t)... print(vagao)vagao #1 • devolve geradorvagao #2vagao #3 • invoca gerador.next() até quevagao #4 ele levante StopIteration @ramalhoorg
  79. 79. Construtores embutidosque consomem eproduzem iteráveis• dict • reversed• enumerate • set• frozenset • tuple• list @ramalhoorg
  80. 80. Módulo itertools• geradores (potencialmente) infinitos • count(), cycle(), repeat()• geradores que combinam vários iteráveis • chain(), tee(), izip(), imap(), product(), compress()...• geradores que selecionam ou agrupam itens: • compress(), dropwhile(), groupby(), ifilter(), islice()...• Iteradores que produzem combinações • product(), permutations(), combinations()... @ramalhoorg
  81. 81. Exemplo prático comfunções geradoras• Funções geradoras para desacoplar laços de leitura e escrita em uma ferramenta para conversão de bases de dados semi-estruturadashttps://github.com/ramalho/isis2json @ramalhoorg
  82. 82. Laço principal escrevearquivo JSON @ramalhoorg
  83. 83. Um outro laço lê osregistros a converter @ramalhoorg
  84. 84. Implementação possível:o mesmo laço lê e grava @ramalhoorg
  85. 85. Mas e a lógica para leroutro formato? @ramalhoorg
  86. 86. Funçõesdo script • iterMstRecords* • iterIsoRecords* • writeJsonArray • main * funções geradoras @ramalhoorg
  87. 87. Função main:leitura dosargumentos @ramalhoorg
  88. 88. Função main: seleçãodo formato escolha dadepende geradora de leitura função dode entrada formato de entrada função geradora escolhida é passada como argumento @ramalhoorg
  89. 89. writeJsonArray:escreverregistrosem JSON @ramalhoorg
  90. 90. writeJsonArray:itera sobre umas dasfunções geradoras @ramalhoorg
  91. 91. iterIsoRecords:ler registros função geradora!de arquivoISO-2709 @ramalhoorg
  92. 92. iterIsoRecords cria um novo dict a cada iteração produz (yield) registro na forma de um dict @ramalhoorg
  93. 93. iterMstRecords: função geradora!ler registrosde arquivoISIS .MST @ramalhoorg
  94. 94. iterMstRecordsiterIsoRecords cria um novo dict a cada iteração produz (yield) registro na forma de um dict @ramalhoorg
  95. 95. Geradores na prática @ramalhoorg
  96. 96. Geradores na prática @ramalhoorg
  97. 97. Geradores na prática @ramalhoorg
  98. 98. Oficinas Turing: computação para programadores• Próximos lançamentos: • 4ª turma de Python para quem sabe Python • 3ª turma de Objetos Pythonicos • 1ª turma de Aprenda Python com um Pythonista Turing.com.br

×