python class method-overloading

¿Cómo uso la sobrecarga de métodos en Python?



class method-overloading (12)

Estoy tratando de implementar la sobrecarga de métodos en Python:

class A: def stackoverflow(self): print ''first method'' def stackoverflow(self, i): print ''second method'', i ob=A() ob.stackoverflow(2)

pero el resultado es el second method 2 ; similar:

class A: def stackoverflow(self): print ''first method'' def stackoverflow(self, i): print ''second method'', i ob=A() ob.stackoverflow()

da

Traceback (most recent call last): File "my.py", line 9, in <module> ob.stackoverflow() TypeError: stackoverflow() takes exactly 2 arguments (1 given)

¿Cómo hago que esto funcione?


Acabo de encontrar este https://github.com/bintoro/overloading.py para cualquiera que pueda estar interesado.

Del archivo léame del repositorio vinculado:

la sobrecarga es un módulo que proporciona despacho de función en función de los tipos y el número de argumentos de tiempo de ejecución.

Cuando se invoca una función sobrecargada, el despachador compara los argumentos suministrados con las firmas de función disponibles y llama a la implementación que proporciona la coincidencia más precisa.

Caracteristicas

La validación de funciones durante el registro y las reglas de resolución detalladas garantizan un resultado único y bien definido en el tiempo de ejecución. Implementa el almacenamiento en caché de resolución de funciones para un gran rendimiento. Admite parámetros opcionales (valores predeterminados) en las firmas de función. Evalúa los argumentos posicionales y de palabra clave al resolver la mejor coincidencia. Admite funciones de respaldo y ejecución de código compartido. Apoya el polimorfismo de argumento Admite clases y herencia, incluidos classmethods y staticmethods.


Creo que la palabra que estás buscando es "sobrecargar". No hay sobrecarga de método en Python. Sin embargo, puede usar argumentos predeterminados, de la siguiente manera.

def (self, i=None): if i != None: print ''second method'', i else: print ''first method''

Cuando le pasa un argumento, seguirá la lógica de la primera condición y ejecutará la primera declaración de impresión. Cuando no le pase argumentos, entrará en la condición else y ejecutará la segunda instrucción de impresión.


En Python, harías esto con un argumento predeterminado.

class A: def (self, i=None): if i == None: print ''first method'' else: print ''second method'',i


En Python, la sobrecarga no es un concepto aplicado. Sin embargo, si está intentando crear un caso donde, por ejemplo, quiere que se realice un inicializador si pasa un argumento de tipo foo y otro inicializador para un argumento de tipo bar entonces, dado que todo en Python se maneja como objeto, usted puede verificar el nombre del tipo de clase del objeto pasado y escribir un manejo condicional basado en eso.

class A: def __init__(self, arg) # Get the Argument''s class type as a String argClass = arg.__class__.__name__ if argClass == ''foo'': print ''Arg is of type "foo"'' ... elif argClass == ''bar'': print ''Arg is of type "bar"'' ... else print ''Arg is of a different type'' ...

Este concepto se puede aplicar a múltiples escenarios diferentes a través de diferentes métodos según sea necesario.


En Python, no haces las cosas de esa manera. Cuando las personas hacen eso en idiomas como Java, generalmente quieren un valor predeterminado (si no lo hacen, generalmente quieren un método con un nombre diferente). Entonces, en Python, puede tener valores predeterminados .

class A(object): # Remember the ``object`` bit when working in Python 2.x def (self, i=None): if i is None: print ''first form'' else: print ''second form''

Como puede ver, puede usar esto para activar el comportamiento por separado en lugar de simplemente tener un valor predeterminado.

>>> ob = A() >>> ob.() first form >>> ob.(2) second form


En el archivo MathMethod.py

from multipledispatch import dispatch @dispatch(int,int) def Add(a,b): return a+b @dispatch(int,int,int) def Add(a,b,c): return a+b+c @dispatch(int,int,int,int) def Add(a,b,c,d): return a+b+c+d

En archivo Main.py

import MathMethod as MM print(MM.Add(200,1000,1000,200))

Podemos sobrecargar el método usando multipledispatch


Es sobrecarga de método, no anulación de método. Y en Python, lo haces todo en una función:

class A: def (self, i=''some_default_value''): print ''only method'' ob=A() ob.(2) ob.()

No puede tener dos métodos con el mismo nombre en Python, y no es necesario.

Consulte la sección Valores de argumento predeterminados del tutorial de Python. Consulte "Menos asombro" y el argumento predeterminado mutable para evitar un error común.

Editar : consulte PEP 443 para obtener información acerca de las nuevas funciones genéricas de envío único en Python 3.4.


Escribo mi respuesta en Python 2.7:

En Python, la sobrecarga de métodos no es posible; si realmente desea acceder a la misma función con diferentes funciones, le sugiero que vaya a la anulación de métodos.

class Base(): # Base class ''''''def add(self,a,b): s=a+b print s'''''' def add(self,a,b,c): self.a=a self.b=b self.c=c sum =a+b+c print sum class Derived(Base): # Derived class def add(self,a,b): # overriding method sum=a+b print sum add_fun_1=Base() #instance creation for Base class add_fun_2=Derived()#instance creation for Derived class add_fun_1.add(4,2,5) # function with 3 arguments add_fun_2.add(4,2) # function with 2 arguments


Escribo mi respuesta en Python 3.2.1.

def overload(*functions): return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

Cómo funciona:

  1. overload toma cualquier cantidad de callables y los almacena en functions tupla, luego devuelve lambda.
  2. La lambda toma cualquier cantidad de argumentos, luego devuelve el resultado de la función de llamada almacenada en functions[number_of_unnamed_args_passed] llamado con argumentos pasados ​​a la lambda.

Uso:

class A: =overload( / None, / #there is always a self argument, so this should never get called lambda self: print(''First method''), / lambda self, i: print(''Second method'', i) / )


No puedes, nunca necesitas y realmente no quieres hacerlo.

En Python, todo es un objeto. Las clases son cosas, entonces son objetos. También lo son los métodos.

Hay un objeto llamado A que es una clase. Tiene un atributo llamado . Solo puede tener uno de esos atributos.

Cuando escribe def (...): ... , lo que ocurre es que crea un objeto que es el método y lo asigna al atributo de A Si escribe dos definiciones, la segunda reemplaza a la primera, de la misma manera que la asignación siempre se comporta.

Además, no desea escribir código que describa el tipo de cosas a las que a veces se aplica la sobrecarga. Así no es como funciona el lenguaje.

En lugar de intentar definir una función separada para cada tipo de cosa que se le podría dar (lo cual tiene poco sentido ya que de todos modos no especifica tipos para los parámetros de función), deje de preocuparse por lo que son y empiece a pensar qué pueden hacer .

No solo no puede escribir uno separado para manejar una tupla frente a una lista, sino que tampoco desea o necesita hacerlo .

Todo lo que haces es aprovechar el hecho de que ambos son, por ejemplo, iterables (es decir, puedes escribir for element in container: . (El hecho de que no estén directamente relacionados por herencia es irrelevante).


Python no es compatible con la sobrecarga de métodos como Java o C ++. Podemos sobrecargar los métodos, pero solo podemos usar el último método definido.

# First sum method. # Takes two argument and print their sum def sum(a, b): s = a + b print(s) # Second sum method # Takes three argument and print their sum def product(a, b, c): s = a + b + c print(s) # Uncommenting the below line shows an error # sum(4, 5) # This line will call the second product method sum(4, 5, 5)

Necesitamos proporcionar argumentos opcionales o * args para proporcionar diferentes números de argumentos en las llamadas.

Cortesía de https://www.geeksforgeeks.org/python-method-overloading/


También puedes usar pythonlangutil :

from pythonlangutil.overload import Overload, signature class A: @Overload @signature() def (self): print ''first method'' @.overload @signature("int") def (self, i): print ''second method'', i