Sobrecarga de operadores e igualdade
Programação
Orientada a Objetos
(com Python)
Prof. Rodrigo Rocha <rodrigorgs@ufba.br>
Instituto de Computação
Universidade Federal da Bahia
Sobrecarga de operadores
Operadores
Python define vários operadores, como +, -, /, //, %, *, ==, !=, <, >, <=, >=, =, +=, -=, *=, /=, //=, %=, dentre outros
3
Operadores são açúcar sintático
Operadores são apenas uma forma amigável de escrever chamadas a métodos
4
Usando operadores | Usando nome do método |
a + b | a.__add__(b) |
a - b | a.__sub__(b) |
a == b | a.__eq__(b) |
str(x) | x.__str__() |
… |
Sobrecarga de operadores
Ao criar uma classe, você pode redefinir esses métodos, efetivamente definindo o código a ser executado quando os operadores são executados com objetos da sua classe
Essa redefinição é chamada de sobrecarga de operadores.
5
Exemplo: sobrecarga�da adição (+)
6
class Fruta:
def __init__(self, nome):
self.nome = nome
def __add__(self, outra_fruta):
prefixo = self.nome[0:4]
sufixo = outra_fruta.nome[3:]
return Fruta(prefixo + sufixo)
abacate = Fruta('abacate')
banana = Fruta('banana')
print(banana + abacate)
Exemplo:
string
7
class Pessoa:
def __init__(self, nome, sobrenome):
self.nome = nome
self.sobrenome = sobrenome
def __repr__(self):
return self.nome + ' ' + self.sobrenome
pessoa = Pessoa('Fulano', 'de tal')
print(pessoa)
Equivalente a
print(str(pessoa))
Retorna a representação do objeto como string
Ver também: __str__
Igualdade
Motivação
9
lista = ['a', 'b', 'c']
if 'c' in lista:
print('Pertence')
Compara 'e' com cada elemento da lista:�'c' == 'a' ⇒ False�'c' == 'b' ⇒ False
'c' == 'c' ⇒ True
Exemplo
10
class Aluno:
def __init__(self, matricula, nome):
self.matricula = matricula
self.nome = nome
lista = [
Aluno('111', 'Fulana'),
Aluno('222', 'Sicrano')
]
a = Aluno('111', 'Fulana')
if a in lista:
print('Presente')
Operador == (__eq__)
11
Exemplo com
__eq__
12
class Aluno:
def __init__(self, matricula, nome):
self.matricula = matricula
self.nome = nome
def __eq__(self, outro):
if isinstance(outro, Aluno):
return self.matricula == outro.matricula
else:
return False
isinstance(obj, classe) retorna True somente se obj é uma instância da classe classe
Exemplo
Considerando a classe definida anteriormente, qual a saída do programa ao lado?
13
lista = [
Aluno('111', 'Fulana'),
Aluno('222', 'Sicrano')
]
a = Aluno('111', 'XYZ')
if a in lista:
print('Presente')
Código hash (__hash__)
14
Exemplo
15
class Aluno:
def __init__(self, matricula, nome):
self.matricula = matricula
self.nome = nome
def __hash__(self):
return hash(self.matricula)
def __eq__(self, outro):
if isinstance(outro, Aluno):
return self.matricula == outro.matricula
else:
return False
hash(x) equivale a x.__hash__()
Código hash e imutabilidade
16
Ordenação
Método sort
18
Operador | Método |
== | __eq__ |
< | __lt__ |
<= | __le__ |
> | __gt__ |
>= | __ge__ |
* Na prática o método sort só usa == e <, mas devemos implementar os demais comparadores para tornar nosso código resiliente a mudanças na implementação do sort
Exemplo
19
from functools import total_ordering
@total_ordering
class Aluno:
def __init__(self, matricula, nome):
self.matricula = matricula
self.nome = nome
def __lt__(self, outro):
if isinstance(outro, Aluno):
return self.matricula < outro.matricula
return NotImplemented
def __eq__(self, outro):
if isinstance(outro, Aluno):
return self.matricula == outro.matricula
return False
Data classes
Data classes
Data classes foram introduzidas no Python 3.7 e permitem escrever classes de forma sucinta, gerando automaticamente métodos como __init__, __eq__, __repr__, dentre outros (a depender das opções fornecidas)
21
Exemplo
Note que a implementação automaticamente gerada leva em consideração todos os atributos e nem sempre é isso que desejamos (nesse caso específico, gostaríamos de usar matrícula para verificar igualdade e ordem)
22
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class Aluno:
matricula: str
nome: str = "Aluno"
Tópicos avançados
23
Conclusão
Contexto
A depender do contexto onde queremos usar os objetos das classes que definimos, podemos precisar sobrecarregar alguns operadores:
25