image

Access unlimited bootcamps and 650+ courses forever

60
%OFF
Article image
Andre Borges
Andre Borges22/11/2024 14:37
Share

As diferenças entre os métodos __new__ e __init__ em classes Python.

  • #Python

Introdução

De forma bem objetiva e direto ao ponto, há duas diferenças principais entre os métodos __new__ e __init__:

  • A primeira diferença é que __new__ é responsável por alocar a memória que abrigará a nova instância da classe retornando essa instancia. Já __init__ inicializa o objeto instanciado por __new__ e retorna None. Inicializar é atribuir valores iniciais aos atributos da instância, enquanto instanciar é alocar memória para instância.
  • A segunda diferença é que __new__ pode ser sobre escrito para mudar a forma, o comportamento, de como um objeto é instanciado. Já o __init__ afeta apenas o estado inicial do objeto, não interferindo em seu processo de criação, ou sua existência, em memória.

Aplicações do método __new__.

O método __new__ pode ser aplicado em alguns cenários interessante como:

  • Aplicação do padrão de projeto Singleton;
  • Subclasse imutável de tuple;
  • Subclasse imutável de str;
  • Cache ou reaproveitamento de objetos criados.

Em seguida iremos abordar cada um desses casos com um pequeno exemplo pratico. Você pode ter acesso a um arquivo no google colab para testar os códigos de exemplo, click aqui.

Neste artigo eu trago apenas um pequeno exemplo didático. Mais exemplos estão disponíveis no google colab.

Padrão de projeto Singleton:

Nesse padrão de projeto instanciamos, um único objeto de uma classe, e sempre reaproveitamos essa instancia quando necessário.

Se você tenta criar uma segunda instância da classe, ela verifica se a classe já foi instanciada alguma vez, se sim, ela te retorna o objeto previamente instanciado, se não ela instancia um novo objeto e o retorna.

O objeto instanciado é guardado como um atributo da classe.

class Singleton:
  _instance = None

  def __new__(cls, *args, **kwargs):
      if not cls._instance:
          cls._instance = super().__new__(cls)  # Criação única da instância
      return cls._instance

  def __init__(self, valor):
      self.valor = valor

# Teste
s1 = Singleton(10)
s2 = Singleton(20)

print(s1 is s2)  # True, ambas são a mesma instância
print(s1.valor)  # 20, `__init__` pode sobrescrever o valor
Share
Comments (0)