Um dos recursos menos conhecidos, mas valiosos, do Python é a capacidade de implementar métodos mágicos em objetos. Usando métodos mágicos, podemos escrever um código mais limpo, intuitivo e fácil de entender.
Com métodos mágicos, podemos criar interfaces para interagir com objetos de uma forma que pareça mais Pythonic. Este artigo irá apresentá-lo aos métodos mágicos, discutir as melhores práticas para criá-los e explorar os métodos mágicos comuns que você encontrará.
últimas postagens
O que são métodos mágicos?
Métodos mágicos são métodos Python que definem como os objetos Python se comportam quando operações comuns são executadas neles. Esses métodos são claramente definidos com sublinhados duplos antes e depois do nome do método.
Como resultado, eles são comumente chamados de métodos dunder, como em sublinhado duplo. Um método comum que você já deve ter encontrado é o método __init__() que é usado para definir construtores de classe.
Normalmente, os métodos dunder não devem ser chamados diretamente em seu código; em vez disso, eles serão chamados pelo interpretador enquanto o programa está sendo executado.
Por que os métodos mágicos são úteis?
Métodos mágicos são um conceito útil em Programação Orientada a Objetos em Python. Usando-os, você especifica o comportamento de seus tipos de dados customizados quando eles são usados com operações integradas comuns. Essas operações incluem:
🟢 Operações aritméticas
🟢 Operações de comparação
🟢 Operações de ciclo de vida
🟢 Operações de representação
A seção a seguir discutirá como implementar métodos mágicos que definem como o aplicativo se comporta quando usado em todas as categorias acima.
Como definir métodos mágicos
Como mencionado anteriormente, os métodos mágicos especificam o comportamento dos objetos. Como tal, eles são definidos como parte da classe do objeto. Por fazerem parte da classe de objeto, eles recebem como primeiro argumento self, que é uma referência ao próprio objeto.
Eles podem receber argumentos adicionais, dependendo de como serão chamados pelo interpretador. Eles também são claramente definidos com dois sublinhados antes e depois de seus nomes.
Implementação
Muito do que discutimos até agora parece teórico e abstrato. Nesta seção, implementaremos uma classe Rectangle simples.
Esta classe terá propriedades de comprimento e largura. Usando o método __init__, você pode especificar essas propriedades na instanciação. Além disso, você poderá comparar diferentes retângulos para ver se é igual, menor ou maior que outro usando os operadores ==, < e >. Por fim, o retângulo deve ser capaz de fornecer uma representação de string significativa.
Configurando o ambiente de codificação
Para acompanhar este passo a passo, você precisará de um ambiente de tempo de execução do Python. Você pode usar um local ou pode usar o compilador on-line etechpt.com Python.
Criando a Classe Retângulo
Primeiro, vamos começar definindo a classe Rectangle.
class Rectangle: pass
Criando o Método Construtor
Em seguida, vamos criar nosso primeiro método mágico, o método construtor de classe. Este método irá pegar a altura e a largura e armazená-los como atributos na instância da classe.
class Rectangle: def __init__(self, height, width): self.height = height self.width = width
Criando um método mágico para representação de string
Em seguida, queremos criar um método que permita que nossa classe gere uma string legível para representar o objeto. Este método será chamado sempre que chamarmos a função str() passando uma instância da classe Rectangle como argumento. Esse método também será chamado quando você chamar funções que esperam um argumento de string, como a função print.
class Rectangle: def __init__(self, height, width): self.height = height self.width = width def __str__(self): return f'Rectangle({self.height}, {self.width})'
O método __str__() deve retornar uma string que você gostaria de representar o objeto. Neste caso, estamos retornando uma string no formato Rectangle(
Criando métodos mágicos para operações de comparação
Em seguida, queremos criar operadores de comparação para as operações igual a, menor que e maior que. Isso é chamado de sobrecarga do operador. Para criá-los, usamos os métodos mágicos __eq__, __lt__ e __gt__ respectivamente. Esses métodos retornarão um valor booleano após a comparação das áreas dos retângulos.
class Rectangle: def __init__(self, height, width): self.height = height self.width = width def __str__(self): return f'Rectangle({self.height}, {self.width})' def __eq__(self, other): """ Checking for equality """ return self.height * self.width == other.height * other.width def __lt__(self, other): """ Checking if the rectangle is less than the other one """ return self.height * self.width < other.height * other.width def __gt__(self, other): """ Checking if the rectage is greater than the other one """ return self.height * self.width > other.height * other.width
Como você pode ver, esses métodos aceitam dois parâmetros. O primeiro é o retângulo atual e o segundo é o outro valor com o qual está sendo comparado. Esse valor pode ser outra ocorrência de Rectangle ou qualquer outro valor. A lógica de como a comparação e as condições sob as quais a comparação retornará verdadeira dependem inteiramente de você.
Métodos Mágicos Comuns
Nesta próxima seção, discutiremos os métodos mágicos comuns que você encontrará e usará.
#1. Operaçoes aritimeticas
Métodos mágicos aritméticos são chamados quando uma instância de sua classe é colocada no lado esquerdo de um sinal aritmético. O método será chamado com dois argumentos, sendo o primeiro uma referência à instância. O segundo valor é o objeto à direita do sinal. Os métodos e sinais são os seguintes:
NameMethodSignDescriptionAddition__add__+Implementa adição. Subtraction__sub__–Implementa a subtração.Multiplication__mul__*Implementa a multiplicaçãoDivisão__div__/Implementa a divisão.Floor division__floordiv__//Implementa a divisão do piso.
#2. Operações de comparação
Como os métodos mágicos aritméticos, esses métodos são chamados quando uma instância da classe para a qual eles são definidos é colocada à esquerda do operador de comparação. Além disso, como os métodos mágicos aritméticos, eles são chamados com dois parâmetros; a primeira é uma referência à instância do objeto. A segunda é uma referência ao valor do lado direito do sinal.
NameMethodSignDescriptionLess than__lt__
#3. Operações de ciclo de vida
Esses métodos serão chamados em resposta aos diferentes métodos de ciclo de vida de um objeto, como ser instanciado ou excluído. O construtor __init__ se enquadra nessa categoria. Os métodos comuns nesta categoria estão listados na tabela abaixo:
NameMethodDescriptionConstructor__init__Este método é chamado sempre que um objeto da classe para o qual está definido é excluído. Ele pode ser usado para executar ações de limpeza, como fechar qualquer arquivo que tenha aberto.Deletion__del__Este método é chamado sempre que um objeto da classe para o qual foi definido é excluído. Ele pode ser usado para executar ações de limpeza, como fechar qualquer arquivo que tenha aberto. New__new__O método __new__ é chamado primeiro quando um objeto da classe especificada é instanciado. Esse método é chamado antes do construtor e recebe a classe, bem como quaisquer argumentos adicionais. Ele retorna uma instância da classe. Na maioria das vezes, não é muito útil, mas é abordado em detalhes aqui.
#4. Operações de representação
NameMethodDescriptionStr__str__Retorna uma representação de string legível por humanos do objeto. Esse método é chamado quando você chama a função str(), passando uma instância da classe como argumento. Também é chamado quando você passa na instância para as funções print() e format(). Destina-se a fornecer uma string que seja compreensível pelo usuário final do aplicativo.Repr__repr__Retorna uma representação de string do objeto que é usado pelo desenvolvedor. Idealmente, a string retornada deve ser rica em informações de forma que você possa construir uma instância idêntica do objeto apenas a partir da string.
Melhores práticas para criar métodos mágicos
Métodos mágicos são incríveis e irão simplificar seu código. No entanto, é importante manter as seguintes coisas em mente ao usá-los.
- Use-os com moderação – Implementar muitos métodos mágicos em suas classes torna seu código difícil de entender. Limite-se a implementar apenas os essenciais.
- Certifique-se de entender as implicações de desempenho de métodos como __setatrr__ e __getattr__ antes de usá-los.
- Documente o comportamento de seus métodos mágicos para que outros desenvolvedores possam saber exatamente o que eles fazem. Isso torna mais fácil para eles usá-los e depurar quando necessário.
Palavras Finais
Neste artigo, apresentei métodos mágicos como uma forma de criar classes que podem ser usadas com operações integradas. Eu também discuti como eles são definidos e passei por um exemplo de uma classe que implementou métodos mágicos. Em seguida, mencionei os diferentes métodos que você provavelmente usará e precisará antes de compartilhar algumas práticas recomendadas a serem lembradas.
Em seguida, você pode querer aprender como implementar a classe Counter em Python.