Como Usar Python facilmente para Iniciantes?
Operador e Sobrecarga de Funções em Classes Python Personalizadas
por Malay Agarwal
O Modelo de Dados do Python
Digamos que você tenha uma classe que represente um pedido online, contendo um carrinho (uma lista) e um cliente (uma string ou uma instância de outra classe que representa um cliente).
Nesse caso, é natural querer obter o tamanho da lista de carrinho. Alguém novo no Python pode decidir implementar um método chamado get_cart_len()
em sua classe para fazer isso. Mas é possível configurar a função embutida len()
de forma que ela retorne o comprimento da lista de carrinho quando receber nosso objeto como argumento.
Outro exemplo seria quando queremos adicionar algo ao carrinho. Novamente, alguém novo no Python pode pensar em implementar um método chamado append_to_cart()
que recebe um item e o adiciona à lista de carrinho. Mas é possível configurar o operador +
de forma que ele adicione um novo item ao carrinho.
O Python faz tudo isso usando métodos especiais. Esses métodos especiais permitem que você substitua o comportamento padrão dos operadores e funções embutidas para trabalhar com os objetos da sua classe personalizada.
Os Detalhes das Operações como len() e []
Os objetos em Python têm a capacidade de responder a várias operações internas, como len()
, acessar elementos por índice ([]
) e outras. Por exemplo, podemos ter uma lista de inteiros e obter o tamanho dessa lista usando a função len()
. No entanto, como usar a mesma função em uma classe personalizada?
Ao usar a função len()
em uma classe personalizada, o Python procura pelo método especial __len__()
no objeto e retorna o resultado desse método. Se não houver um método __len__()
definido, um erro será gerado.
Podemos personalizar o comportamento da função len()
em nossa classe personalizada definindo o método __len__()
na classe. Vamos ver um exemplo:
No exemplo acima, definimos o método __len__()
em nossa classe Cart
que retorna o comprimento da lista items
. Agora, quando chamamos a função len()
em um objeto Cart
, o Python chama o método __len__()
definido na classe e retorna o resultado.
Sobrecarga de Funções Embutidas
Além da função len()
, podemos sobrecarregar outras funções embutidas do Python para trabalhar com objetos de nossa classe personalizada.
Dando um Tamanho aos Objetos Usando len()
Já vimos como sobrecarregar a função embutida len()
. Agora, vamos ver como podemos fazer isso com outras funções embutidas.
Digamos que queremos que nossa classe Cart
possa ser convertida em uma string usando a função str()
embutida. Podemos fazer isso definindo o método __str__()
em nossa classe. Veja um exemplo:
Neste exemplo, definimos o método __str__()
em nossa classe Cart
que retorna uma string formatada para ser exibida quando chamamos a função str()
em um objeto Cart
.
Fazendo os Objetos Funcionarem com abs()
Podemos sobrecarregar a função embutida abs()
para trabalhar com nossos objetos personalizados. Por exemplo, digamos que queremos calcular o valor absoluto do total de itens no carrinho. Podemos fazer isso definindo o método __abs__()
em nossa classe Cart
. Veja um exemplo:
No exemplo acima, definimos o método __abs__()
em nossa classe Cart
que calcula o valor absoluto da quantidade de itens no carrinho. Agora, quando chamamos a função abs()
em um objeto Cart
, o Python chama o método __abs__()
definido na classe e retorna o resultado.
Imprimindo os Objetos de Forma Bonita Usando repr()
Podemos sobrecarregar a função embutida repr()
para fornecer uma representação mais amigável dos nossos objetos personalizados. Por exemplo, digamos que queremos que nosso objeto Cart
seja impresso de forma bonita ao usar a função repr()
. Podemos fazer isso definindo o método __repr__()
em nossa classe. Veja um exemplo:
Neste exemplo, definimos o método __repr__()
em nossa classe Cart
que retorna uma representação do objeto em forma de string. Agora, quando chamamos a função repr()
em um objeto Cart
, o Python chama o método __repr__()
definido na classe e retorna o resultado.
Tornando os Objetos Falsos ou Verdadeiros Usando bool()
Podemos sobrecarregar a função embutida bool()
para determinar se nossos objetos personalizados são falsos ou verdadeiros. Por exemplo, digamos que queremos que nosso objeto Cart
seja considerado verdadeiro apenas se houver pelo menos um item no carrinho. Podemos fazer isso definindo o método __bool__()
em nossa classe. Veja um exemplo:
Neste exemplo, definimos o método __bool__()
em nossa classe Cart
que retorna True
se houver pelo menos um item no carrinho e False
se não houver nenhum item. Agora, quando chamamos a função bool()
em um objeto Cart
, o Python chama o método __bool__()
definido na classe e retorna o resultado.
Sobrecarga de Operadores Embutidos
Além das funções embutidas, também podemos sobrecarregar operadores embutidos para trabalhar com nossos objetos personalizados.
Tornando os Objetos Capazes de Serem Somados Usando +
Podemos sobrecarregar o operador +
para adicionar objetos da nossa classe personalizada. Por exemplo, digamos que queremos adicionar dois objetos Cart
para obter um único carrinho com todos os itens. Podemos fazer isso definindo o método __add__()
em nossa classe. Veja um exemplo:
No exemplo acima, definimos o método __add__()
em nossa classe Cart
que retorna um novo objeto Cart
contendo todos os itens dos carrinhos somados. Agora, quando usamos o operador +
entre dois objetos Cart
, o Python chama o método __add__()
definido na classe e retorna o novo carrinho combinado.
Atalhos: o Operador +=
Podemos fornecer um atalho para a operação de adição ao implementar o operador +=
em nossa classe personalizada. Por exemplo, digamos que queremos adicionar um item a um carrinho de forma mais conveniente, usando o operador +=
. Podemos fazer isso definindo o método __iadd__()
em nossa classe. Veja um exemplo:
No exemplo acima, definimos o método __iadd__()
em nossa classe Cart
que adiciona um item à lista de carrinho e retorna o próprio objeto Cart
. Agora, quando usamos o operador +=
em um objeto Cart
, o Python chama o método __iadd__()
definido na classe e realiza a operação de adição diretamente no objeto.
Indexando e Fatiando Objetos Usando []
Podemos sobrecarregar o operador []
para indexar e fatiar objetos de nossa classe personalizada. Por exemplo, digamos que queremos acessar um item específico no carrinho ou obter uma parte do carrinho como uma nova lista. Podemos fazer isso definindo os métodos __getitem__()
e __setitem__()
em nossa classe. Veja um exemplo:
No exemplo acima, definimos os métodos __getitem__()
e __setitem__()
em nossa classe Cart
que permitem o acesso aos itens da lista de carrinho usando o operador []
. Além disso, modificamos o valor de um item específico no carrinho definindo um novo valor usando o operador []
acompanhado pelo operador =
.
Operadores Reversos: Tornando as Classes Matematicamente Corretas
Podemos sobrecarregar operadores reversos para tornar nossas classes compatíveis com operações matemáticas. Por exemplo, digamos que queremos que nosso objeto Cart
possa ser adicionado a um número inteiro ou a uma lista. Podemos fazer isso definindo os métodos __radd__()
e __radd__()
em nossa classe. Veja um exemplo:
No exemplo acima, definimos os métodos __radd__()
e __add__()
em nossa classe Cart
para fornecer suporte à adição reversa. Agora, podemos adicionar um objeto Cart
a um número inteiro ou a uma lista usando o operador +
da forma correta.
Um Exemplo Completo
Agora que você entende como sobrecarregar operadores e funções embutidas em classes Python personalizadas, vamos ver um exemplo completo. Imagine que queremos criar uma classe para representar uma matriz bidimensional. Queremos que essa classe possa ser adicionada e subtraída de outras matrizes, seja indexada e fatiada, e que possa ser multiplicada por um escalar. Veja o exemplo abaixo:
Neste exemplo, estamos usando uma classe Matrix
para representar matrizes bidimensionais. Sobrecarregamos os operadores +
, -
e *
para adicionar, subtrair e multiplicar matrizes, respectivamente. Também sobrecarregamos os operadores []
para indexar e fatiar as matrizes. Todos esses operadores fornecem o comportamento esperado para matrizes.
Resumo e Recursos
Neste artigo, você aprendeu como sobrecarregar operadores e funções embutidas em classes Python personalizadas. Você viu como usar métodos especiais para substituir o comportamento padrão dos operadores e funções embutidas para trabalhar com objetos de suas classes personalizadas.
Lembre-se de que a sobrecarga de operadores e funções embutidas pode tornar seus objetos mais Pythonicos e oferecer uma experiência mais conveniente e intuitiva ao trabalhar com eles.
Recursos adicionais de Python: