privados - ¿Cómo puedo acceder a un método de clase desde dentro de una clase en Python?
metodos en python (4)
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
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.
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 manera 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 class, no importaría, porque la clase aún no existe, por lo que el método class 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 ejecutarla más tarde de la forma que describe, use un decorador de clase. El decorador de 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
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, por lo 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
Usted llama a un método de clase agregando el nombre de la clase de la misma manera:
class.method
En tu 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