Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Magic Methods: O que são? Como vivem? Do que se alimentam? Por que são "magic"?

Magic Methods: O que são? Como vivem? Do que se alimentam? Por que são "magic"?

A ideia desta palestra é apresentar "magic methods" que é um poderoso recurso da linguagem Python e que deixam nossas vidas mais simples!

Resumo:

- Demonstrar como a linguagem Python poderia ser horrível;
- Explicar o que é "açúcar sintático";
- Explicando o que é um magic method;
- Overview sobre magic methods comuns;
- Implementações úteis de magic methods na vida real.

Transcript

  1. Magic Methods O que são? Como vivem? Do que se

    alimentam? Por que são "magic"?
  2. Eu Rafael Henrique da Silva Correia @rafaelhenrique http://blog.abraseucodigo.com.br - Desenvolvedor

    Python na Olist (temos vagas!) - Aprendiz de Golang - Rogue em World of Warcraft - Aspirante a Mestre em Ciências da Computação - Não gosto de Java!
  3. Método Método de uma classe é uma ação designada a

    determinado objeto “criado” a partir daquela classe. class TV: def ligar(self): codigo_que_liga_tv()
  4. Método Método de uma classe é uma ação designada a

    determinado objeto “criado” a partir daquela classe. >>> tv_sala = TV() >>> dir(tv_sala) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ligar']
  5. Método “mágico” Método “mágico” (ou também chamado de especial) são

    métodos com nomes predefinidos com usos específicos que não devem ser chamados diretamente pois eles geralmente são chamados “por baixo dos panos” >>> tv_sala = TV() >>> dir(tv_sala) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ligar']
  6. Método “mágico” Método “mágico” (ou também chamado de especial) são

    métodos com nomes predefinidos com usos específicos que não devem ser chamados diretamente pois eles geralmente são chamados “por baixo dos panos” >>> tv_sala = TV() >>> dir(tv_sala) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ligar'] Nota especial: É mais “classudo” falar dunder init (__init__), dunder add (__add__) … etc Falar underline underline init underline underline é muito custoso e exige muito processamento mental :)
  7. Em Python tudo é objeto! Python é mais Orientado a

    Objetos do que Java! Não temos tipos primitivos. >>> dir(1) ['__abs__', '__add__', '__and__', '__bool__', …, 'imag', 'numerator', 'real', 'to_bytes'] >>> dir(‘a’) ['__add__', '__class__', '__contains__', '__delattr__', …, 'title', 'translate', 'upper', 'zfill']
  8. Açúcar sintático (syntax sugar) Usar coisas “bonitas” para traduzir coisas

    “feias” (verbosas) >>> (40).__add__(50) 90 >>> 40 + 50 90 >>> (50).__add__(20) 70 >>> 50 + 20 70
  9. Açúcar sintático (syntax sugar) Exemplo de como o Python poderia

    ser um lixo igual Java complicado: class Calculadora: def soma(x, y): return x.__add__(y) def subtracao(x, y): return x.__sub__(y) def __repr__(self): return ‘calculadora ruim’ calc = Calculadora() print(calc.__repr__()) result = calc.soma(1, 2) class Calculadora: def soma(x, y): return x + y def subtracao(x, y): return x - y def __repr__(self): return ‘calculadora boa’ calc = Calculadora() print(calc) result = calc.soma(1, 2)
  10. Pra que magic method? [1] Para podermos estender/modificar funcionalidades e

    manter o comportamento Pythônico / açúcar sintático >>> (40).__add__(50) 90 >>> 40 + 50 90 >>> (50).__add__(20) 70 >>> 50 + 20 70
  11. Pra que magic method? [1] Vamos criar um tipo novo

    no Python chamado Measure que pode somar duas medidas de forma simples: class Measure: units = {"cm": 0.01, "m": 100} def __init__(self, value, unit): self.value = value self.unit = unit def convert_units(self, measure): return self.units[measure.unit] * measure.value def __add__(self, measure): return self.value + self.convert_units(measure)
  12. Pra que magic method? [1] - Somando metros com centímetros

    obtemos a medida em metros; - Somando centímetros com metros obtemos a medida em centímetros. >>> m = Measure(1, 'm') >>> cm = Measure(100, 'cm') >>> cm + m 200 >>> m + cm 2.0
  13. Pra que magic method? [2] Vamos criar um formatador de

    datas ! (exemplo 8.2 do Python Cookbook) _formats = { 'ymd': '{d.year}-{d.month}-{d.day}', 'mdy': '{d.month}/{d.day}/{d.year}', } class Date: def __init__(self, year, month, day): self.year = year self.month = month self.day = day def __format__(self, code): if code == '': code = 'ymd' fmt = _formats[code] return fmt.format(d=self)
  14. Pra que magic method? [2] Formatando 13/07/2018... >>> date =

    Date(2018, 7, 13) >>> format(date) '2018-7-13' >>> format(date, 'ymd') '2018-7-13' >>> format(date, 'mdy') '7/13/2018'
  15. Pra que magic method? [3] Criando um contador de tempo

    com gerenciamento de contexto (baseado no post) ... import time class Timer: def __init__(self, name): self.name = name def __enter__(self): self.start = time.time() def __exit__(self, *args): end = time.time() print("{} took {} seconds".format(self.name, end - self.start)) return False
  16. Pra que magic method? [3] Criando um contador de tempo

    com gerenciamento de contexto ... >>> import time >>> with Timer('o processo é lento'): ... time.sleep(3) ... o processo é lento took: 3.003 seconds >>> with Timer('abacaxi'): ... print('Just Python') ... Just Python abacaxi took: 0.000 seconds
  17. Quais as mágicas dos magic methods? Resposta simples: Muitas! Resposta

    longa com alguns exemplos: • Criar coleções iteráveis; • Criar “tipos” novos (Descriptors); • Criar classes chamáveis que “fingem” ser funções (Callables); • Criar gerenciadores de contexto; • … etc … etc … (algum palpite extra?)
  18. Referências • Dive into Python 3 • Python Course •

    Descriptors (Ramalho) • Sem __mágica__ (Ramalho) • Documentação oficial
  19. Obrigado! Perguntas!? Rafael Henrique da Silva Correia @rafaelhenrique http://blog.abraseucodigo.com.br