Eu quero saber a diferença entre __init__
e __call__
métodos.
Por exemplo:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
O primeiro é usado para inicializar o objeto recém-criado e recebe argumentos usados para fazer isso:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
O segundo implementa o operador de chamada de função.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
__init__
método é usado quando a classe é chamada para inicializar a instância, enquanto o__call__
método é chamado quando a instância é chamada__call__
?Definir um
__call__()
método personalizado na meta-classe permite que a instância da classe seja chamada como uma função, nem sempre modificando a própria instância.fonte
__call__
não apenas permite que uma instância seja usada como uma função ... ela define o corpo da função que é executada quando uma instância é usada como uma função.No Python, funções são objetos de primeira classe, isto significa: referências de funções podem ser passadas em entradas para outras funções e / ou métodos, e executadas a partir delas.
Instâncias de classes (também conhecidas como Objetos), podem ser tratadas como se fossem funções: passe-as para outros métodos / funções e as chame. Para conseguir isso, o
__call__
função de classe precisa ser especializada.def __call__(self, [args ...])
Toma como entrada um número variável de argumentos. Supondo quex
seja uma instância da ClasseX
,x.__call__(1, 2)
é análogo a chamadax(1,2)
ou a própria instância como uma função .No Python,
__init__()
é definido corretamente como Construtor de Classes (assim como__del__()
o Destruidor de Classes). Portanto, existe uma distinção nítida entre__init__()
e__call__()
: o primeiro cria uma instância de Class up, o segundo torna essa instância exigível como uma função sem afetar o ciclo de vida do próprio objeto (por exemplo,__call__
é, não construção / destruição), mas ele pode modificar seu estado interno (como mostrado abaixo).Exemplo.
fonte
def __call__
simplesmente pordef update
, damos à classe umupdate
método que faz a mesma coisa. Agora também pode modificar o estado interno, se chamado abaixo comos.update(7, 8)
. Então, é__call__
apenas o açúcar syntactix?__call__
torna instável a instância de uma classe. Por que isso seria necessário?Tecnicamente,
__init__
é chamado uma vez__new__
quando o objeto é criado, para que possa ser inicializado.Mas há muitos cenários em que você pode redefinir seu objeto, dizer que terminou com ele e pode encontrar a necessidade de um novo objeto. Com
__call__
você pode redefinir o mesmo objeto como se fosse novo.Este é apenas um caso, pode haver muito mais.
fonte
fonte
__init__
seria tratado como Construtor, onde__call__
métodos podem ser chamados com objetos inúmeras vezes. Ambas as funções__init__
e__call__
recebem argumentos padrão.fonte
__init__
não é uma função construtora, mas__new__
é.__init__
é chamado logo após__new__
__new__
cria a instância da classe e recebe uma classe como argumento, enquanto que__init__
é o construtor da instância e é por isso que ele recebeself
. Uma maneira fácil de ver isso é na chamadaa = Foo(1,2,3)
a função que receberá os argumentos do construtor__init__
.Vou tentar explicar isso usando um exemplo, suponha que você queira imprimir um número fixo de termos da série fibonacci. Lembre-se de que os 2 primeiros termos da série fibonacci são 1s. Por exemplo: 1, 1, 2, 3, 5, 8, 13 ....
Você deseja que a lista que contém os números de fibonacci seja inicializada apenas uma vez e depois seja atualizada. Agora podemos usar a
__call__
funcionalidade. Leia a resposta de @mudit verma. É como se você desejasse que o objeto pudesse ser chamado como uma função, mas não reinicializado toda vez que você o chama.Por exemplo:
A saída é:
Se você observar que a saída
__init__
foi chamada apenas uma vez, foi quando a classe foi instanciada pela primeira vez, mais tarde, o objeto foi chamado sem ser reinicializado.fonte
Você também pode usar o
__call__
método em favor da implementação de decoradores .Este exemplo, retirado de Python 3 Patterns, Recipes e Idioms
Saída :
fonte
Então,
__init__
é chamado quando você está criando uma instância de qualquer classe e inicializando a variável de instância também.Exemplo:
E
__call__
é chamado quando você chama o objeto como qualquer outra função.Exemplo:
fonte
__init__
é um método especial nas classes Python, é o método construtor de uma classe. É chamado sempre que um objeto da classe é construído ou podemos dizer que inicializa um novo objeto. Exemplo:Se usarmos A (), ocorrerá um erro
TypeError: __init__() missing 1 required positional argument: 'a'
, pois requer 1 argumentoa
por causa de__init__
.........
__call__
quando implementado na classe nos ajuda a chamar a instância de classe como uma chamada de função.Exemplo:
Aqui, se usarmos B (), ele funciona muito bem porque não tem uma
__init__
função aqui.fonte
__call__
permite retornar valores arbitrários, enquanto__init__
ser construtor retorna a instância da classe implicitamente. Como outras respostas apontaram corretamente,__init__
é chamado apenas uma vez, enquanto é possível chamar__call__
várias vezes, caso a instância inicializada seja atribuída à variável intermediária.fonte
Respostas curtas e doces já são fornecidas acima. Eu quero fornecer alguma implementação prática em comparação com Java.
Nota : os cenários 1 e 2 parecem iguais em termos de resultado. Mas no cenário1, criamos novamente outra nova instância1 . No cenário2, simplesmente modificamos a instância1 criada já .
__call__
é benéfico aqui, pois o sistema não precisa criar uma nova instância.Equivalente em Java
fonte
Podemos usar o método de chamada para usar outros métodos de classe como métodos estáticos.
fonte