Requisito previo: constructores , @classmethod decoradores
Python no admite constructores múltiples explícitos, sin embargo, hay algunas formas en que se pueden lograr los constructores múltiples. Si se escriben varios métodos __init__ para la misma clase, el último sobrescribe todos los constructores anteriores. Mira el ejemplo de abajo.
Python3
class example: def __init__(self): print("One") def __init__(self): print("Two") def __init__(self): print("Three") e = example()
Three
Necesidad de múltiples constructores
Se requieren múltiples constructores cuando uno tiene que realizar diferentes acciones en la instanciación de una clase. Esto es útil cuando la clase tiene que realizar diferentes acciones en diferentes parámetros. Los constructores de clases se pueden hacer para exhibir polimorfismo de tres maneras que se enumeran a continuación.
- Sobrecarga de constructores basados en argumentos.
- Llamar a métodos desde __init__ .
- Usando el decorador @classmethod .
Este artículo explica cómo tener múltiples constructores de una manera limpia y pythonica con ejemplos.
Sobrecarga de constructores basados en argumentos
La sobrecarga del constructor se realiza comprobando las condiciones de los argumentos pasados y realizando las acciones requeridas. Por ejemplo, considere pasar un argumento a la clase muestra ,
- Si el parámetro es un int , el cuadrado del número debería ser la respuesta.
- Si el parámetro es una string , la respuesta debe ser «¡¡Hola!!» + string.
- Si el parámetro tiene una longitud superior a 1, la suma de los argumentos debe almacenarse como respuesta.
Python3
class sample: # constructor overloading # based on args def __init__(self, *args): # if args are more than 1 # sum of args if len(args) > 1: self.ans = 0 for i in args: self.ans += i # if arg is an integer # square the arg elif isinstance(args[0], int): self.ans = args[0]*args[0] # if arg is string # Print with hello elif isinstance(args[0], str): self.ans = "Hello! "+args[0]+"." s1 = sample(1, 2, 3, 4, 5) print("Sum of list :", s1.ans) s2 = sample(5) print("Square of int :", s2.ans) s3 = sample("GeeksforGeeks") print("String :", s3.ans)
Sum of list : 15 Square of int : 25 String : Hello! GeeksforGeeks.
En el código anterior, la variable de instancia era ans , pero sus valores difieren según los argumentos. Dado que hay un número variable de argumentos para la clase, se usa *args , que es una tupla que contiene los argumentos pasados y se puede acceder mediante un índice. En el caso de int y string, solo se pasa un argumento y, por lo tanto, se accede como args[0] (el único elemento en la tupla).
Llamar a métodos desde __init__
Una clase puede tener un constructor __init__ que puede realizar cualquier acción cuando se crea la instancia de la clase. Este constructor se puede hacer para diferentes funciones que realizan diferentes acciones en función de los argumentos pasados. Ahora considere un ejemplo:
- Si el número de argumentos pasados es 2, entonces evalúe la expresión x = a 2 -b 2
- Si el número de argumentos pasados es 3, entonces evalúe la expresión y = a 2 +b 2 -c.
- Si se han pasado más de 3 argumentos, sume los cuadrados y divídalos por el valor más alto de los argumentos pasados.
Python3
class eval_equations: # single constructor to call other methods def __init__(self, *inp): # when 2 arguments are passed if len(inp) == 2: self.ans = self.eq2(inp) # when 3 arguments are passed elif len(inp) == 3: self.ans = self.eq1(inp) # when more than 3 arguments are passed else: self.ans = self.eq3(inp) def eq1(self, args): x = (args[0]*args[0])+(args[1]*args[1])-args[2] return x def eq2(self, args): y = (args[0]*args[0])-(args[1]*args[1]) return y def eq3(self, args): temp = 0 for i in range(0, len(args)): temp += args[i]*args[i] temp = temp/max(args) z = temp return z inp1 = eval_equations(1, 2) inp2 = eval_equations(1, 2, 3) inp3 = eval_equations(1, 2, 3, 4, 5) print("equation 2 :", inp1.ans) print("equation 1 :", inp2.ans) print("equation 3 :", inp3.ans)
equation 2 : -3 equation 1 : 2 equation 3 : 11.0
En el ejemplo anterior, la ecuación a evaluar se escribe en diferentes métodos de instancia y se hace para devolver la respuesta. El constructor llama al método apropiado y actúa de manera diferente para diferentes parámetros.
Las expresiones han sido evaluadas de la siguiente manera:
entradas : 1,2 —> 1 2 -2 2 = 1-4 = -3
entradas : 1,2,3 —> (1 2 +2 2 ) – 3 = 5-3 = 2
entradas : 1,2,3,4,5 —> (1 2 + 2 2 + 3 2 + 4 2 + 5 2 ) / 5 = 55/5 = 11.0
Usando el decorador @classmethod
Este decorador permite que una función sea accesible sin instanciar la clase. Se puede acceder a las funciones tanto por la instancia de la clase como por la propia clase. El primer parámetro del método que se declara como classmethod es cls, que es como el self de los métodos de instancia. Aquí cls se refiere a la clase misma. Esto demuestra ser muy útil para usar múltiples constructores en Python y es un enfoque más pythonico que los anteriores. Considere el mismo ejemplo utilizado anteriormente. Evaluar diferentes expresiones basadas en el número de entradas.
Python3
class eval_equations: # basic constructor def __init__(self, a): self.ans = a # expression 1 @classmethod def eq1(cls, args): # create an object for the class to return x = cls((args[0]*args[0])+(args[1]*args[1])-args[2]) return x # expression 2 @classmethod def eq2(cls, args): y = cls((args[0]*args[0])-(args[1]*args[1])) return y # expression 3 @classmethod def eq3(cls, args): temp = 0 # square of each element for i in range(0, len(args)): temp += args[i]*args[i] temp = temp/max(args) z = cls(temp) return z li = [[1, 2], [1, 2, 3], [1, 2, 3, 4, 5]] i = 0 # loop to get input three times while i < 3: inp = li[i] # no.of.arguments = 2 if len(inp) == 2: p = eval_equations.eq2(inp) print("equation 2 :", p.ans) # no.of.arguments = 3 elif len(inp) == 3: p = eval_equations.eq1(inp) print("equation 1 :", p.ans) # More than three arguments else: p = eval_equations.eq3(inp) print("equation 3 :", p.ans) #increment loop i += 1
equation 2 : -3 equation 1 : 2 equation 3 : 11.0
En el ejemplo anterior, la instancia del objeto no se crea inicialmente. Los métodos de clase para evaluar varias expresiones se han definido con el decorador @classmethod . Ahora se pueden llamar con el nombre de la clase y el objeto se crea en ese método de clase después de evaluar la expresión. La variable de instancia contiene diferentes respuestas para un número diferente de parámetros pasados.
Publicación traducida automáticamente
Artículo escrito por erakshaya485 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA