Métodos estáticos: ¿cómo llamar a un método desde otro método?

96

Cuando tengo métodos regulares para llamar a otro método en una clase, tengo que hacer esto

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

pero cuando tengo métodos estáticos no puedo escribir

self.dosomethingelse()

porque no hay instancia. ¿Cómo tengo que hacer en Python para llamar a un método estático desde otro método estático de la misma clase?

Editar: qué lío. Ok, volví a editar la pregunta a la pregunta original. Ya tengo la respuesta a la segunda pregunta que está en el comentario de Peter Hansen. Si cree que debería abrir otra pregunta para obtener una respuesta que ya tengo, por favor dígame.

Pablo
fuente
3
@pablo: no se puede cambiar la esencia de la pregunta !! ¡Termina esta pregunta y comienza otra !
jldupont
bien bien. ¿te refieres a eliminar la pregunta? La respuesta ya está en el comentario de Peter Hansen
Pablo
@pablo: no puede eliminar aquí eso no sería de buena educación para todos los que contribuyeron con respuestas a su pregunta. Debe aceptar una respuesta y crear una nueva pregunta.
jldupont
1
@pablo: y para ser claro: se debe aceptar una respuesta para la formulación de la pregunta original . No se preocupe, aprenderá a moverse por aquí. Saludos :-)
jldupont

Respuestas:

79

class.method Deberia trabajar.

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()
jldupont
fuente
17
Se debe agregar un consejo aquí: está claro que los métodos de clase no tienen inconvenientes sobre los métodos estáticos, y los métodos de clase permiten que el método se extienda en el futuro para llamar a otros métodos de clase. Por lo tanto, siempre debe preferirse, aunque no haya una necesidad inmediata.
u0b34a0f6ae
1
@ u0b34a0f6ae: No sé si estoy haciendo algo bueno o no ... pero definí un decorador dentro de una clase. El decorador tenía que ser un "método estático", no un "método de clase".
André Caldas
@ u0b34a0f6ae ¿Son los métodos de clase siempre seguros para subprocesos? En mi caso de uso, estoy usando métodos estáticos en subprocesos para evitar el acceso accidental a la clase que puede no ser segura para subprocesos.
aquavitae
@ u0b34a0f6ae siempre es un poco fuerte. Por ejemplo, el uso de PySpark staticmethods se puede usar en trabajos rdd y los classmethods no.
Laurens Koppenol
136

¿Cómo tengo que hacer en Python para llamar a un método estático desde otro método estático de la misma clase?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()
warvariuc
fuente
La llamada también Test.static_method_to_call()debería funcionar desde otros métodos no estáticos y sin clase de esta clase, ¿verdad? (... ¿y probablemente otras clases también?)
gr4nt3d
Sí, Test.static_method_to_call()funcionará desde cualquier lugar.
warvariuc
11

NOTA: parece que la pregunta ha cambiado un poco. La respuesta a la pregunta de cómo llamar a un método de instancia desde un método estático es que no puede sin pasar una instancia como argumento o instanciar esa instancia dentro del método estático.

Lo que sigue es principalmente para responder "cómo se llama a un método estático desde otro método estático":

Tenga en cuenta que no es una diferencia entre los métodos estáticos y métodos de clase en Python. Un método estático no toma un primer argumento implícito, mientras que un método de clase toma la clase como el primer argumento implícito (generalmente clspor convención). Con eso en mente, así es como lo haría:

Si es un método estático:

test.dosomethingelse()

Si es un método de clase:

cls.dosomethingelse()
Jason Baker
fuente
1
solo puede usar cls.dosomethingelse()desde dentro de la definición de clase.
jldupont
3
Para ser más precisos, solo puede usar cls.dosomethingelse()desde el propio método de clase. Al igual que solo puede usar selfdesde dentro de un método de instancia.
Jason Baker
1
lo siento, escribí mal la pregunta. OOPS !. Quería escribir "¿Cómo tengo que hacerlo en Python para llamar a un método de instancia desde otro método estático de la misma clase?" Y no "¿Cómo tengo que hacerlo en Python para llamar a un método estático desde otro método estático del mismo? clase "
Pablo
@pablo: En este caso, debes escribir otra pregunta y terminar esta.
jldupont
@jldupont, ya tengo la respuesta pero en un comentario. ¿Qué debo hacer porque no puedo aceptarlo pero sería un desperdicio borrar la pregunta, no?
Pablo
4

OK, la principal diferencia entre los métodos de clase y los métodos estáticos es:

  • El método de clase tiene su propia identidad, por eso deben llamarse desde dentro de una INSTANCIA.
  • por otro lado, el método estático se puede compartir entre varias instancias, por lo que debe ser llamado desde dentro de THE CLASS
Ahmad Dwaik
fuente
0

no puede llamar a métodos no estáticos desde métodos estáticos, pero creando una instancia dentro del método estático ... debería funcionar así

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

Espero que te ayude :)

Ahmad Dwaik
fuente
3
En mi opinión, este enfoque es notablemente peor que solo usarlo @classmethodpara declarar sus métodos y usarlo cls.dosomethingelse()dentro cls.dosomething(), peor en términos de rendimiento (instanciar objetos solo para obtener acceso a un método estático) y legibilidad (no es sencillo, y me imagino si ese tipo del patrón se convirtió en estándar, todo el código base podría volverse bastante difícil de analizar para un simple humano)
Kyle Wild
Como leí en otro lugar en SO, en lugar de inicializar la instancia directamente para llamar a un método, puede simplemente llamarlo, se iniciará por sí solo.
Nakilon
0

Si estos no dependen de la clase o instancia, ¿por qué no convertirlos en una función? Ya que esto parecería la solución obvia. A menos que, por supuesto, piense que será necesario sobrescribirlo, subclase, etc. Si es así, las respuestas anteriores son la mejor opción. Crucemos los dedos. No me marcarán por ofrecer simplemente una solución alternativa que puede o no satisfacer las necesidades de alguien;).

Como la respuesta correcta dependerá del caso de uso del código en cuestión;) Disfruta

AppHandwerker
fuente