¿Cómo puedo acceder a un método de clase desde dentro de una clase en Python?

Me gustaría crear una clase en Python que administre por encima de todos los miembros estáticos. Estos miembros deben ser iniciados durante la definición de la clase ya. Debido al hecho de que será necesario reinicializar los miembros estáticos más adelante, pondría este código en un método de clase.

Mi pregunta: ¿Cómo puedo llamar a este método de clase desde dentro de la clase?

class Test(): # static member x = None # HERE I WOULD LOVE TO CALL SOMEHOW static_init! # initialize static member in classmethod, so that it can be #reinitialized later on again @classmethod def static_init(cls): cls.x = 10 

Cualquier ayuda es apreciada!

Gracias de antemano, Volker

En el momento en que se ejecuta x=10 en su ejemplo, no solo no existe la clase, sino que tampoco existe el método class.

La ejecución en Python va de arriba a abajo. Si x=10 está por encima del método de clase, no hay forma de que pueda acceder al método de clase en ese punto, porque aún no se ha definido.

Incluso si pudieras ejecutar el método de clase, no importaría, porque la clase aún no existe, por lo que el método de clase no podría referirse a él. La clase no se crea hasta después de que se ejecute todo el bloque de clase, por lo que mientras esté dentro del bloque de clase, no hay clase.

Si desea factorizar alguna inicialización de clase para poder volver a ejecutarla más adelante de la manera que describe, use un decorador de clase. El decorador de la clase se ejecuta después de que se crea la clase, por lo que puede llamar al método class muy bien.

 >>> def deco(cls): ... cls.initStuff() ... return cls >>> @deco ... class Foo(object): ... x = 10 ... ... @classmethod ... def initStuff(cls): ... cls.x = 88 >>> Foo.x 88 >>> Foo.x = 10 >>> Foo.x 10 >>> Foo.initStuff() # reinitialize >>> Foo.x 88 

Usted llama a un método de clase agregando el nombre de la clase de la misma manera:

 class.method 

En su código algo como esto debería ser suficiente:

 Test.static_init() 

También podrías hacer esto:

 static_init(Test) 

Para llamarlo dentro de tu clase , haz que tu código haga esto:

 Test.static_init() 

Mi código de trabajo:

 class Test(object): @classmethod def static_method(cls): print("Hello") def another_method(self): Test.static_method() 

y Test().another_method() devuelve Hello

No se puede llamar a un classmethod de class en la definición de class porque la clase aún no se ha definido completamente, así que no hay nada para pasar el método como su primer argumento cls … un problema clásico de la gallina y el huevo. Sin embargo, puede __new__() esta limitación sobrecargando el __new__() en una metaclase, y llamar al método class desde allí después de que se haya creado la clase como se ilustra a continuación:

 class Test(object): # nested metaclass definition class __metaclass__(type): def __new__(mcl, classname, bases, classdict): cls = type.__new__(mcl, classname, bases, classdict) # creates class cls.static_init() # call the classmethod return cls x = None @classmethod def static_init(cls): # called by metaclass when class is defined print("Hello") cls.x = 10 print Test.x 

Salida:

 Hello 10 

Después de volver a leer su pregunta con cuidado, esta vez puedo pensar en dos soluciones. El primero es aplicar el patrón de diseño Borg. La segunda es descartar el método de clase y usar una función de nivel de módulo en su lugar. Esto parece resolver su problema:

 def _test_static_init(value): return value, value * 2 class Test: x, y = _test_static_init(20) if __name__ == "__main__": print Test.x, Test.y 

Respuesta vieja, incorrecta:

Aquí hay un ejemplo, espero que ayude:

 class Test: x = None @classmethod def set_x_class(cls, value): Test.x = value def set_x_self(self): self.__class__.set_x_class(10) if __name__ == "__main__": obj = Test() print Test.x obj.set_x_self() print Test.x obj.__class__.set_x_class(15) print Test.x 

De todos modos, la respuesta de NlightNFotis es mejor: use el nombre de la clase cuando acceda a los métodos de la clase. Hace que su código sea menos oscuro.