Métodos Mágicos em Python

Métodos Mágicos em Python

Este artigo explica os métodos mágicos em Python.

YouTube Video

Métodos Mágicos em Python

Os métodos mágicos (métodos especiais) em Python são métodos com nomes especiais usados para dar comportamentos únicos às classes. Por exemplo, eles são caracterizados por estarem entre dois sublinhados (dunders), como __init__ e __str__. Portanto, também são chamados de métodos dunder.

Ao definir métodos mágicos, você pode personalizar o comportamento padrão das classes. Por exemplo, definir o __add__ permite alterar o comportamento do operador +.

Métodos Mágicos para Inicialização e Representação em String

__init__: Método de Inicialização

O método __init__ é um construtor chamado automaticamente quando uma instância é criada.

1class Person:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5
6person = Person("Alice", 30)
7print(person.name)  # Alice

__str__: Representação em String Legível

O método __str__ retorna uma representação em string legível para humanos. Ele é chamado por print() e str().

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __str__(self):
6        return f"Person: {self.name}"
7
8person = Person("Bob")
9print(person)  # Person: Bob

__repr__: Representação em String voltada para Debug

O método __repr__ retorna uma representação em string para fins de depuração. É usado pelo repr() e ao exibir no interpretador.

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __repr__(self):
6        return f"Person(name={self.name!r})"
7
8person = Person("Eve")
9print(repr(person))  # Person(name='Eve')

Sobrecarga de Operadores Aritméticos

__add__: Operador +

Usando métodos mágicos, operadores aritméticos podem ser sobrecarregados. Por exemplo, o método __add__ permite a sobrecarga do operador +.

 1class Vector:
 2    def __init__(self, x, y):
 3        self.x = x
 4        self.y = y
 5
 6    def __add__(self, other):
 7        return Vector(self.x + other.x, self.y + other.y)
 8
 9    def __repr__(self):
10        return f"Vector({self.x}, {self.y})"
11
12    # Other arithmetic magic methods:
13    # def __sub__(self, other):       # Subtraction (-)
14    # def __mul__(self, other):       # Multiplication (*)
15    # def __truediv__(self, other):   # True division (/)
16    # def __floordiv__(self, other):  # Floor division (//)
17    # def __mod__(self, other):       # Modulo (%)
18    # def __pow__(self, other):       # Exponentiation (**)
19
20v1 = Vector(1, 2)
21v2 = Vector(3, 4)
22print(v1 + v2)  # Vector(4, 6)

Outros métodos mágicos aritméticos incluem:.

Método Operador
__add__ +
__sub__ -
__mul__ *
__truediv__ /
__floordiv__ //
__mod__ %
__pow__ **

Personalizando Operadores de Comparação

Você também pode sobrecarregar operadores de comparação. Por exemplo, o método __eq__ sobrecarrega o operador de igualdade.

 1class Box:
 2    def __init__(self, volume):
 3        self.volume = volume
 4
 5    def __eq__(self, other):
 6        return self.volume == other.volume
 7
 8    def __lt__(self, other):
 9        return self.volume < other.volume
10
11    # Comparison magic methods:
12    # def __eq__(self, other):  # Equal to (==)
13    # def __ne__(self, other):  # Not equal to (!=)
14    # def __lt__(self, other):  # Less than (<)
15    # def __le__(self, other):  # Less than or equal to (<=)
16    # def __gt__(self, other):  # Greater than (>)
17    # def __ge__(self, other):  # Greater than or equal to (>=)
18
19b1 = Box(100)
20b2 = Box(200)
21
22print(b1 == b2)  # False
23print(b1 < b2)   # True

Também existem os seguintes métodos mágicos:. Esses métodos mágicos definem comparações como igualdade e ordenação entre objetos.

Operador Método Mágico
== __eq__
!= __ne__
< __lt__
<= __le__
> __gt__
>= __ge__

Métodos Mágicos para Tipos de Contêiner

Você pode criar classes que se comportam como listas ou dicionários.

__len__: Obtendo o Número de Elementos

O método __len__ é um método mágico que retorna o número de elementos.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __len__(self):
6        return len(self.items)
7
8basket = Basket(["apple", "banana"])
9print(len(basket))  # 2

__getitem__: Acesso por Índice

O método __getitem__ é chamado ao usar acesso por índice.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __getitem__(self, index):
6        return self.items[index]
7
8basket = Basket(["apple", "banana"])
9print(basket[1])  # banana

__setitem__ e __delitem__: Escrita e Exclusão

Os métodos __setitem__ e __delitem__ são chamados ao escrever ou remover itens.

 1class Basket:
 2    def __init__(self, items):
 3        self.items = items
 4
 5    def __setitem__(self, index, value):
 6        self.items[index] = value
 7
 8    def __delitem__(self, index):
 9        del self.items[index]
10
11basket = Basket(["apple", "banana"])
12basket[1] = "grape"
13del basket[0]
14print(basket.items)  # ['grape']

Métodos Mágicos para Iteração

Para tornar um objeto iterável em um laço for, implemente o seguinte:.

__iter__ e __next__

 1class Counter:
 2    def __init__(self, limit):
 3        self.limit = limit
 4        self.current = 0
 5
 6    def __iter__(self):
 7        return self
 8
 9    def __next__(self):
10        if self.current >= self.limit:
11            raise StopIteration
12        self.current += 1
13        return self.current
14
15for num in Counter(3):
16    print(num)
17# Output:
18# 1
19# 2
20# 3

Gerenciador de Contexto (Instrução with)

Definindo os métodos __enter__ e __exit__, você pode implementar pré e pós-processamento para a instrução with.

 1class FileOpener:
 2    def __init__(self, filename):
 3        self.filename = filename
 4
 5    def __enter__(self):
 6        self.file = open(self.filename, 'r')
 7        return self.file
 8
 9    def __exit__(self, exc_type, exc_val, exc_tb):
10        self.file.close()
11
12with FileOpener("example.txt") as f:
13    content = f.read()
14    print(content)

Objetos Chamáveis: __call__

Definindo o método __call__, você pode fazer uma instância ser chamada como uma função.

1class Greeter:
2    def __init__(self, greeting):
3        self.greeting = greeting
4
5    def __call__(self, name):
6        return f"{self.greeting}, {name}!"
7
8hello = Greeter("Hello")
9print(hello("Alice"))  # Hello, Alice!

Resumo

Os métodos mágicos em Python são uma forma poderosa de adicionar comportamento natural e intuitivo às classes. Cada método tem uma finalidade clara, e implementá-los corretamente permite que você escreva códigos mais flexíveis e Pythonicos.

Os métodos mágicos funcionam como uma ‘interface invisível’ que suporta como os objetos Python interagem e se comportam nos bastidores.

Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.

YouTube Video