Pular para o conteúdo

Métodos especiais

Definição

Python considera que uma classe pode ter dois tipos de métodos: métodos criados pelo programador e métodos especiais que são embutidos na linguagem.

Métodos especiais são identificados por um sublinhado duplo em cada lado do nome, como __new__ e __init__. Esse tipo de método é chamado automaticamente, quando necessário, pelo programa. Por exemplo, quando um novo objeto é criado, o Python chama automaticamente o método __new__, que por sua vez chama o método __init__.

Não é possível chamar os métodos especiais explicitamente no programa, mas é possível alterá-los dentro das classes. O exemplo abaixo altera o método especial __add__ para a operação “+” e o método especial __init__ para a inicialização das variáveis. Essas alterações são válidas apenas para objetos da classe Valor.

class Valor:
   def __init__(self, valor):
      print("Inicializa variável com", valor)
      self.valor = valor  
   def __add__(self, outro):
      print("Valores somados:", self.valor, "e", outro.valor)
      return Valor(self.valor + outro.valor)
a = Valor(15)
b = Valor(8)
c = a + b
print("Resultado =", c.valor)

A resposta do programa é:

Inicializa variável com 15
Inicializa variável com 8
Valores somados: 15 e 8
Inicializa variável com 23
Resultado = 23

Para mais detalhes sobre métodos especiais, veja https://docs.python.org/3/reference/datamodel.html#special-method-names.

Exemplos

  • Exemplo: Definir uma classe e criar um objeto dessa classe no Python é bastante simples. O script abaixo define a classe Aluno e depois cria o objeto aluno da classe Aluno.
class Aluno:
    nome = "Maria Flor"
aluno = Aluno()
print("Nome = ", aluno.nome)

A saída do programa é:

Nome =  Maria Flor

Quando a instância de uma classe é criada, o Python chama primeiro o método __new__() para criar o objeto e, em seguida, chama o método __init__() para inicializar os atributos do objeto. Para alterar esses métodos, basta a classe defini-los dentro do seu escopo.

class Aluno:
    def __new__(cls, name):
        print(f'1 - Cria um novo objeto {cls.__name__}')
        objeto = object.__new__(cls)
        return objeto
    def __init__(self, nome):
        print('2 - Inicializa o objeto')
        self.nome = nome
aluno = Aluno('Maria Flor')
print("Nome =", aluno.nome)

Observe que a função __name__ é usada para obter o nome da classe. Abaixo a resposta do programa.

1 - Cria um novo objeto Aluno
2 - Inicializa o objeto
Nome = Maria Flor
  • Exemplo: a função __del__ pode ser usada para deletar objetos ou atributos de objetos.
class Aluno:
   def __init__(self, nome, curso):
      self.nome  = nome
      self.curso = curso
   def __del__(self):
      print('Atributo deletado')
aluno = Aluno("Maria Flor", "BSI")
print("Antes da deleção:", vars(aluno))
del aluno.curso
print("Depois da deleção", vars(aluno))

A saída do programa é mostrada abaixo.

Antes da deleção: {'nome': 'Maria Flor', 'curso': 'BSI'}
Depois da deleção {'nome': 'Maria Flor'}
Atributo deletado
  • Exemplo: o programa conta o número de objetos da classe Aluno que existe no ambiente.
class Aluno:
   contador = 0
   def __init__(self, nome, curso):
      self.nome  = nome
      self.curso = curso
      type(self).contador += 1
   def __del__(self):
      type(self).contador -= 1
      print('Aluno deletado:', self.nome)  
aluno1 = Aluno("Maria Flor", "BSI")
aluno2 = Aluno("João Pedro", "BSI")
aluno3 = Aluno("Ana Clara", "BSI")
aluno4 = Aluno("Carlos Luiz", "BSI")
print("Número inicial de alunos =", Aluno.contador)
del aluno2
print("Número final de alunos =", Aluno.contador)
print("*** Fim do programa")

A resposta do programa é mostrada abaixo. Note que após da execução da última linha do programa, os objetos da classe Aluno, que ainda existem, são deletados.

Número inicial de alunos = 4
Aluno deletado: João Pedro
Número final de alunos = 3
*** Fim do programa
Aluno deletado: Maria Flor
Aluno deletado: Ana Clara
Aluno deletado: Carlos Luiz
  • Exemplo: verifica o tamanho do atributo nome da classe Aluno.
class Aluno:
    def __init__(self, nome):
        self.nome = nome
        self.tam  = len(self.nome)
    def __len__(self):
        print("*** Verifica tamanho do nome")
        return self.tam
aluno = Aluno("Maria Flor")
print("1 - Tamanho =", len(aluno))
print("2 - Tamanho =", len(aluno.nome))

A saída do programa é apresentada abaixo. Observe que __len__ espera um objeto da classe Aluno. No primeiro caso, quando o programa chama len(aluno), a função __len__ é executada. No segundo caso, quando o programa chama len(aluno.nome), a função embutida len() é executada, pois uma string é fornecida como argumento.

*** Verifica tamanho do nome
1 - Tamanho = 10
2 - Tamanho = 10