¿Se puede llamar a un método de una clase sin crear una instancia de esa clase?

publicado por: Anonymous

Se crean dos clases:

class SumaExtrana:
    def sumita(self,num1,num2):
        self.a=num1+num2-3
        print(self.a)

class Numero:
    def __init__(self,b=0):
        self.x=3.1524+b

if __name__ == '__main__':
    numero1=Numero(3)
    numero2=Numero(4)
    print(numero1.x,numero2.x)
    #se desea utilizar el método de la clase Suma Extraña sin crear una 
    # instancia de esa clase
    SumaExtrana.sumita(numero1.x,numero2.x)

Sin embargo se tiene este error:

TypeError: sumita() missing 1 required positional argument: ‘num2’

Repito ,se desea solo utilizar el método de la clase SumaExtrana pero sin tener que crear una instancia de la clase, que no se utilizaría en otra parte del código.

solución

La respuesta ya te la ha dado Héctor, esto es solo para ampliar un poco la información.

Si tienes un método declarado como método de instancia, como es tu caso, la respuesta corta es no, no sin modificar la clase original. Ese método tiene como primer parámetro self lo que indica que espera una instacia de la clase. Si ese método no usara ningún atributo de la instancia/clase dentro de él (cosa rara, ya que la razón de ser de un método es modificar el comportamiento/estado de un objeto) “nada” te impide pasarle cualquier cosa a self (excepto porque es una trampa, mala práctica, poco claro, peligroso y queda feo XD):

class SumaExtrana:
    def sumita(self,num1,num2):
        a=num1+num2-3
        print(a)

if __name__ == '__main__':
    SumaExtrana.sumita(None,5,6)

Esto no se debe hacer, pero en tu caso se usa self.a, a es un atributo de instancia por lo que debe recibir como primer parámetro una instancia válida con el atributo a para que pueda funcionar.

Como te comenta Héctor en su respuesta se podría declarar el método como estático mediante el decorador @staticmethod pero eso requiere modificar la clase. Además, cambiar el método a un método estático es equivalente (a grandes rasgos) a sacar el método de la clase y ponerlo como una función global del módulo (la diferencia es el namespace principalmente). La razón de ser de @staticmethod es generalmente brindar la posibilidad de empaquetar y ordenar el código. Además de permitir ordenar el código, también permite que una instancia de la clase pueda sobreescribir el método, cosa que no sería posible si se declarara fuera de la misma.

Declarar el método como estático no implica solo añadir el decorador, implica que ese método no modifica su comportamiento con el estado de la clase y que no puede acceder a los atributos de la clase o instancia más allá de lo que se le pase como argumentos. Es decir, en la clase original no podría usar ni modificar el atributo a ya que este pertenece a la instancia o clase (no defines a en tu ejemplo):

class SumaExtrana:

    @staticmethod
    def sumita(num1,num2):
        a=num1+num2-3
        print(a)

La razón de hacer lo que quieres es no crear una instancia de tu clase por cuestiones de eficiencia, el problema es que el método esta definido como un método de instancia y, además, usa atributos propios de la clase o instancia por lo que no hay forma de hacer lo que quieres sin modificar la clase SumaExtrema.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *