Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Diferença entre construtores entre linguagens

Vi na aula e em outra fonte externa que não se pode chamar o

__init__

em Python de construtor da instância. Que em Java existe o construtor e em Python o método init desempenha papel parecido mas que não pode ser chamado exatamente de construtor.

Por curiosidade queria entender melhor essa diferença. Para entender melhor isso preciso saber Java ou dá pra entender sem ter nenhum conhecimento sobre Java?

5 respostas

Olá Thiago, tudo bem?

Essa dúvida também me perseguiu quando comecei a ver Python haha. Funciona basicamente assim, o __init__ é utilizado para inicializar valores dentro do objeto. Ele não trabalha com a parte de alocação de memória, essas coisas, apenas inicializa os atributos e funcionalidades do objeto. Objeto esse que ele recebe no parâmetro (self).

Antes de criar uma instância da classe, o Python chama outro método mágico, o __new__. Esse método é chamado antes do objeto ser criado - antes de ter memória alocada, essas coisas - e ele devolve uma instância do objeto que é passado como parâmetro para o método __init__.

Thiago,

Na realidade o método __init__ é o inicializador, este é um método especial em Python (chamado __init__) que é chamado automaticamente para configurar um objeto recém-criado no seu estado inicial (padrão de fábrica).

O metodo construtor seria o new, veja o exemplo:

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class aluno:
...    pass
...
>>> thiago = aluno()
>>> dir(thiago)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> 
>>> dir(thiago.__new__)
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']
>>> (thiago.__new__).__doc__
'Create and return a new object.  See help(type) for accurate signature.'
>>>

OBS: No final esta escrito literalmente: "Cria e retorna um novo objeto. Veja ajuda (type) para assinatura precisa.

Use o __new__ quando você precisar controlar a criação de uma nova instância da classe. Use o __init__ quando você precisar controlar a inicialização de uma nova instancia.

O __new__ é o primeiro passo da criação de uma instância. Ele é chamado primeiro, e é responsável por retornar uma nova instancia da sua classe. Em contraste, o __init__ não retorna nada, ele é apenas responsável pela inicialização da instancia após a classe ser criada.

Em geral, você não deveria sobrepor o __new__ ao menos que seja uma subclasse, um tipo imutável como str, int, unicode ou tuple.

Deixa ver se entendi direito. Sou iniciante em OO então tenham paciência comigo rs. Achei a explicação do Welton bastante esclarecedora porém muito detalhada e alguns pontos me geraram certa confusão por não ter tanta base em OO ainda. E a do Yuri foi bem sucinta e entendi bem.

Primeiro, instância e objeto são a mesma coisa? No exemplo acima, thiago é um objeto e instância da classe aluno? Ou tem diferença entre objeto e instância?

Segundo, se for seguida uma ordem cronológica, primeiro é usado o método __new__ para criação do objeto e depois o __init__ para sua inicialização, quando eu quiser declarar características da minha instância, correto?

No exemplo acima, quando eu declarei "thiago" como instância da classe aluno, em:

thiago = aluno()

o Python no fundo dos panos usou o método __new__ e criou o objeto pra mim? Então o __new__ pode ser chamado de construtor, certo?

E em seguida se eu quiser atribuir alguma característica à instância aí que o __init__ entra, correto?

Agradeço as respostas de vocês. Já elucidaram muito essas questões na minha cabeça. Acho que com essas minhas novas perguntas esclarecidas já vou entender melhor tudo isso.

solução!

Olá Thiago, tudo bem?

Isso mesmo, um objeto é uma instância da classe. No exemplo thiago = aluno(). thiago é um objeto - uma instância - da classe aluno.

Se pensarmos em linguagens como Java, o construtor faz os papeis do __new__ e o __init__. O __new__ é o primeiro passo para a criação da instância. Ele retorna a instância da classe.

Já o __init__ não retorna nada, ele é o responsável por inicializar a instância depois da criação.

No Python, por padrão, toda classe herda de type. Ou seja, quando criamos um objeto, o Python vai internamente chamar um método na classe type. Este método chama o método __new__ que recebe a instância (self) do objeto. Essa instância é passada para o método __init__.

Excelentes explicações. Muito obrigado, Yuri e Welton. Já entendi melhor o assunto.