Em Python, os métodos mágicos são métodos especiais que pode definir para adicionar funcionalidades às suas classes. Também são conhecidos como dunder methods, por causa dos sublinhados duplos __ que aparecem antes e depois dos nomes desses métodos. É possível que já tenha visto dois desses métodos: __init__ e __str__. Veja um exemplo simples:
class Circle:
def __init__(self, radius): # Inicializa o objeto
self.radius = radius
def __str__(self): # Representa como string
return f'Circle with radius {self.radius}'
c = Circle(5) # Cria um objeto Circle chamado c
print(c) # Circle with radius 5
No exemplo, definimos dois métodos mágicos:
__init__ é um método construtor que é chamado quando se cria uma instância da classe. Aqui, ele define o raio do Circle.
__str__ define como uma instância da classe deveria ser convertida em string quando usada em contextos como a função print().
Mas estes não são os únicos métodos mágicos em Python. Existem muitos outros. Alguns deles são mostrados abaixo, permitindo que as instâncias da classe possam ser somadas com + ou comparadas com < ou >:
class Circle:
def __init__(self, radius): # Inicializa o objeto
self.radius = radius
def __str__(self): # Representa como string
return f'Circle with radius {self.radius}'
def __add__(self, other): # Adiciona dois círculos
return Circle(self.radius + other.radius) # Retorna um novo círculo
def __lt__(self, other): # Comparação "menos que" entre dois círculos
return self.radius < other.radius # Compara os raios
c1 = Circle(5)
c2 = Circle(7)
c3 = c1 + c2 # This would create a new Circle with radius 12
print(c3) # Circle with radius 12
print(c1 < c2) # True
Nesse caso:
__add__ permite-nos utilizar o operador + com instâncias de Circle. Ele soma o raio dos círculos e devolve um novo Circle.
__lt__ (menos que) permite comparar duas instâncias de Circle com o operador <. Ele verifica se o raio do primeiro círculo é menor do que o do segundo.
Os métodos mágicos tornam as classes em Python mais expressivas e intuitivas, fazendo-as funcionar de maneira semelhante aos objetos nativos da linguagem.
Lembre-se de manter a convenção de sublinhados duplos, pois o interpretador do Python procura especificamente esses nomes especiais para executar certas operações. Pode encontrar a lista completa de métodos mágicos em Python seguindo este link. Abaixo estão alguns dos métodos mágicos mais populares:
Método Mágico
Operador
Descrição
__eq__
==
Retorna True se self for igual a other.
__lt__
<
Retorna True se self for menor que other.
__le__
<=
Retorna True se self for menor ou igual a other.
__gt__
>
Retorna True se self for maior que other.
__ge__
>=
Retorna True se self for maior ou igual a other.
__add__(self, other)
+
Implementa a adição com o operador +.
__sub__(self, other)
-
Implementa a subtração com o operador -.
__mul__(self, other)
*
Implementa a multiplicação com o operador *.
__truediv__(self, other)
/
Implementa a divisão com o operador /.
__floordiv__(self, other)
//
Implementa a divisão inteira com o operador //.
__mod__(self, other)
%
Implementa o módulo com o operador %.
__pow__(self, other)
**
Implementa o operador de potência **.
__abs__(self)
abs()
Implementa o comportamento para a função embutida abs().
__round__(self, n)
round()
Implementa o comportamento para a função embutida round().
__neg__(self)
-
Implementa a negação com o operador unário -.
💡
Note que nem todos os métodos fazem sentido em todas as classes; deve implementar apenas aqueles que sejam realmente úteis para o seu problema.
Desafio: Criar uma Classe Vector
A sua tarefa é definir uma classe, Vector, que representa um vetor tridimensional com atributos x, y e z.
A classe deve incluir a implementação dos métodos especiais __add__, __sub__ e __mul__ para a adição, subtração e o produto interno (dot product) de vetores, respetivamente.
Além disso, implemente um método magnitude para calcular a magnitude (o comprimento) do vetor.
Os métodos solicitados:
__add__: Deve receber outro objeto Vector e retornar um novo Vector que resulte da soma dos componentes x, y e z dos dois vetores.
__sub__: Deve receber outro objeto Vector e retornar um novo Vector que resulte da subtração dos componentes x, y e z do segundo vetor em relação ao primeiro.
__mul__: Deve receber outro objeto Vector e retornar o produto interno dos dois vetores, calculado como:
magnitude: Deve retornar a magnitude (comprimento) do vetor, calculada como: