Quiero saber la diferencia entre __init__y __call__métodos.
Por ejemplo:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
El primero se usa para inicializar el objeto recién creado, y recibe los argumentos utilizados para hacer eso:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
El segundo implementa el operador de llamada de función.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
__init__método se utiliza cuando la clase se llama para inicializar la instancia, mientras que el__call__método se llama cuando la instancia se llama__call__?La definición de un
__call__()método personalizado en la metaclase permite llamar a la instancia de la clase como una función, no siempre modificando la instancia en sí.fuente
__call__no solo permite que una instancia se use como una función ... sino que define el cuerpo de la función que se ejecuta cuando una instancia se usa como una función.En Python, las funciones son objetos de primera clase, esto significa: las referencias de funciones pueden pasarse en entradas a otras funciones y / o métodos, y ejecutarse desde su interior.
Las instancias de clases (también conocidas como objetos) pueden tratarse como si fueran funciones: pasarlas a otros métodos / funciones y llamarlas. Para lograr esto, la
__call__función de clase debe ser especializada.def __call__(self, [args ...])Toma como entrada un número variable de argumentos. Asumir quexes una instancia de la ClaseX,x.__call__(1, 2)es análogo a la llamadax(1,2)o la instancia en sí misma como una función .En Python,
__init__()se define correctamente como Constructor de clase (así como también__del__()es el Destructor de clase). Por lo tanto, hay una distinción neta entre__init__()y__call__(): el primero crea una instancia de Class up, el segundo hace que dicha instancia sea invocable como una función sin afectar el ciclo de vida del objeto en sí (es decir__call__, no afecta el ciclo de vida de construcción / destrucción) pero puede modificar su estado interno (como se muestra a continuación).Ejemplo.
fuente
def __call__simplemente condef update, le damos a la clase unupdatemétodo que hace lo mismo. Ahora también puede modificar el estado interno, si se llama a continuación comos.update(7, 8). Entonces, ¿es__call__solo azúcar sintáctico?__call__hace que la instancia de una clase sea invocable. ¿Por qué se requeriría?Técnicamente
__init__se llama una vez__new__cuando se crea el objeto, para que pueda inicializarse.Pero hay muchos escenarios en los que es posible que desee redefinir su objeto, decir que ha terminado con su objeto y puede encontrar la necesidad de un nuevo objeto. Con
__call__usted puede redefinir el mismo objeto como si fuera nuevo.Este es solo un caso, puede haber muchos más.
fuente
fuente
__init__se trataría como un constructor donde los__call__métodos se pueden llamar con objetos cualquier número de veces. Ambos__init__y las__call__funciones toman argumentos por defecto.fuente
__init__no es una función constructora pero__new__es.__init__se llama justo después__new____new__crea la instancia de la clase y recibe una clase como argumento, mientras__init__que el constructor de la instancia es la razón por la que recibeself. Una manera fácil de ver esto es en la llamadaa = Foo(1,2,3)que será la función que recibirá los argumentos del constructor__init__.Trataré de explicar esto usando un ejemplo, supongamos que desea imprimir un número fijo de términos de las series de Fibonacci. Recuerde que los primeros 2 términos de la serie de Fibonacci son 1s. Por ejemplo: 1, 1, 2, 3, 5, 8, 13 ...
Desea que la lista que contiene los números de Fibonacci se inicialice solo una vez y luego se actualice. Ahora podemos usar la
__call__funcionalidad. Lea la respuesta de @mudit verma. Es como si quisieras que el objeto sea invocable como una función pero no reinicializado cada vez que lo llames.P.ej:
El resultado es:
Si observa que la salida
__init__se llamó solo una vez, fue cuando se instancia la clase por primera vez, más tarde se llamó al objeto sin reinicializar.fuente
También puede usar el
__call__método a favor de implementar decoradores .Este ejemplo tomado de Python 3 Patrones, recetas y modismos
Salida :
fuente
Entonces,
__init__se llama cuando está creando una instancia de cualquier clase e inicializando la variable de instancia también.Ejemplo:
Y
__call__se llama cuando llama al objeto como cualquier otra función.Ejemplo:
fuente
__init__es un método especial en las clases de Python, es el método constructor de una clase. Se llama cada vez que se construye un objeto de la clase o podemos decir que inicializa un nuevo objeto. Ejemplo:Si usamos A (), dará un error
TypeError: __init__() missing 1 required positional argument: 'a'ya que requiere 1 argumentoadebido a__init__.........
__call__cuando se implementa en la Clase, nos ayuda a invocar la instancia de la Clase como una llamada a la función.Ejemplo:
Aquí si usamos B (), funciona bien porque no tiene una
__init__función aquí.fuente
__call__permite devolver valores arbitrarios, mientras que__init__ser un constructor devuelve la instancia de clase implícitamente. Como otras respuestas señalaron correctamente,__init__se llama solo una vez, mientras que es posible llamar__call__varias veces, en caso de que la instancia inicializada se asigne a una variable intermedia.fuente
Respuestas cortas y dulces ya se proporcionan arriba. Quiero proporcionar una implementación práctica en comparación con Java.
Nota : el escenario 1 y el escenario 2 parecen iguales en términos de resultados. Pero en el escenario1, nuevamente creamos otra instancia nueva instancia1 . En el escenario 2, simplemente modificamos la instancia1 ya creada .
__call__es beneficioso aquí ya que el sistema no necesita crear una nueva instancia.Equivalente en Java
fuente
Podemos usar el método call para usar otros métodos de clase como métodos estáticos.
fuente