Métodos mágicos em Python, também conhecidos como métodos dunder (porque possuem sublinhados duplos no início e no final de seus nomes), nos permitem definir o comportamento de nossos objetos para várias operações. Eles permitem um comportamento personalizado e podem fazer com que nossas classes atuem como tipos integrados. Neste blog, exploraremos diferentes categorias de métodos mágicos, forneceremos explicações detalhadas e daremos exemplos práticos e casos de uso.
Esses métodos mágicos controlam como os atributos dos seus objetos são acessados, modificados ou excluídos.
__getattr__: Chamado quando um atributo não é encontrado em um objeto.
__getattribute__: Chamado incondicionalmente para acessar qualquer atributo.
Exemplo: acesso a atributos personalizados com registro
class LoggedAttributes: def __init__(self, name): self.name = name def __getattr__(self, item): print(f"Accessing non-existent attribute: {item}") return None def __getattribute__(self, item): print(f"Getting attribute: {item}") return super().__getattribute__(item) # Usage obj = LoggedAttributes("Alice") print(obj.name) # Output: Getting attribute: name\nAlice print(obj.age) # Output: Accessing non-existent attribute: age\nNone
Caso de uso prático: Registrar o acesso ao atributo em um cenário de depuração para rastrear quando e como os atributos são acessados ou modificados.
__setattr__: Chamado quando uma atribuição de atributo é tentada.
__delattr__: chamado quando uma tentativa de exclusão de atributo é tentada.
Exemplo: modificação de atributo personalizado com validação
class Person: def __init__(self, name, age): self.name = name self.age = age def __setattr__(self, key, value): if key == "age" and valueCaso de uso prático: Aplicação de regras ou restrições de validação ao definir ou excluir atributos.
2. Métodos de contêiner
Esses métodos mágicos permitem que seus objetos se comportem como contêineres (listas, dicionários, etc.).
__len__, __getitem__, __setitem__, __delitem__ e __iter__
__len__: Retorna o comprimento do contêiner.
__getitem__: recupera um item em um determinado índice ou chave.
__setitem__: Define um item em um determinado índice ou chave.
__delitem__: Exclui um item em um determinado índice ou chave.
__iter__: Retorna um objeto iterador.
Exemplo: objeto semelhante a uma lista personalizada
class CustomList: def __init__(self): self._items = [] def __len__(self): return len(self._items) def __getitem__(self, index): return self._items[index] def __setitem__(self, index, value): self._items[index] = value def __delitem__(self, index): del self._items[index] def __iter__(self): return iter(self._items) def append(self, item): self._items.append(item) # Usage cl = CustomList() cl.append(1) cl.append(2) cl.append(3) print(len(cl)) # Output: 3 print(cl[1]) # Output: 2 for item in cl: print(item) # Output: 1 2 3
Caso de uso prático: Criação de uma classe de coleção personalizada que precisa de comportamento especializado ou métodos adicionais, ao mesmo tempo em que oferece suporte a operações de lista padrão.
Esses métodos definem como os objetos da sua classe interagem com operações numéricas e comparações.
Exemplo: classe de número complexo personalizado
class Complex: def __init__(self, real, imag): self.real = real self.imag = imag def __add__(self, other): return Complex(self.real other.real, self.imag other.imag) def __sub__(self, other): return Complex(self.real - other.real, self.imag - other.imag) def __repr__(self): return f"({self.real} {self.imag}i)" # Usage c1 = Complex(1, 2) c2 = Complex(3, 4) print(c1 c2) # Output: (4 6i) print(c1 - c2) # Output: (-2 -2i)
Caso de uso prático: Implementação de tipos numéricos personalizados, como números complexos, vetores ou matrizes.
Exemplo: implementação de pedido total para uma classe personalizada
from functools import total_ordering @total_ordering class Book: def __init__(self, title, author): self.title = title self.author = author def __eq__(self, other): return (self.title, self.author) == (other.title, other.author) def __lt__(self, other): return (self.title, self.author)Caso de uso prático: Permitir que objetos personalizados sejam classificados ou comparados, útil em estruturas de dados como heaps, árvores de pesquisa binária ou simplesmente ao classificar listas de objetos personalizados.
4. Métodos de contêiner: caso de uso prático
Dicionário personalizado com teclas que não diferenciam maiúsculas de minúsculas
Criando um objeto semelhante a um dicionário que trata as chaves como não diferenciando maiúsculas de minúsculas.
Exemplo: dicionário sem distinção entre maiúsculas e minúsculas
class CaseInsensitiveDict: def __init__(self): self._data = {} def __getitem__(self, key): return self._data[key.lower()] def __setitem__(self, key, value): self._data[key.lower()] = value def __delitem__(self, key): del self._data[key.lower()] def __contains__(self, key): return key.lower() in self._data def keys(self): return self._data.keys() def items(self): return self._data.items() def values(self): return self._data.values() # Usage cid = CaseInsensitiveDict() cid["Name"] = "Alice" print(cid["name"]) # Output: Alice print("NAME" in cid) # Output: TrueCaso de uso prático: Criação de dicionários onde as chaves devem ser tratadas sem distinção entre maiúsculas e minúsculas, útil para lidar com entradas do usuário, definições de configuração, etc.
Conclusão
Os métodos mágicos fornecem uma maneira poderosa de personalizar o comportamento de seus objetos em Python. Compreender e usar esses métodos de maneira eficaz pode tornar suas aulas mais intuitivas e integrar-se perfeitamente às funções e operadores integrados do Python. Esteja você implementando tipos numéricos personalizados, contêineres ou padrões de acesso a atributos, os métodos mágicos podem melhorar muito a flexibilidade e a funcionalidade do seu código
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3