Tuve un problema interesante esta mañana. Tenía una clase base que se veía así:Decorar un método que ya es un método de clase?
# base.py
class Base(object):
@classmethod
def exists(cls, **kwargs):
# do some work
pass
y un módulo de decorador que se veía así:
# caching.py
# actual caching decorator
def cached(ttl):
# complicated
def cached_model(ttl=300):
def closure(model_class):
# ...
# eventually:
exists_decorator = cached(ttl=ttl)
model_class.exists = exists_decorator(model_class.exists))
return model_class
return closure
Aquí es mi modelo de subclase:
@cached_model(ttl=300)
class Model(Base):
pass
La cosa es que cuando en realidad llame a Model.exists, ¡recibo quejas sobre la cantidad incorrecta de argumentos! Inspeccionar los argumentos en el decorador no muestra nada extraño: los argumentos son exactamente lo que espero y coinciden con la firma del método. ¿Cómo puedo agregar más decoradores a un método que ya está decorado con classmethod
?
No todos los modelos se almacenan en caché, pero el exists() método está presente en todos los modelos como classmethod, por lo que volver a ordenar los decoradores no es una opción: cached_model
puede agregar a classmethod existe(), pero luego lo hace Existe() ¿un método de clase en modelos no almacenados?
Entonces, ¿cuál es la solución? No es claro. Hubiera sido mucho mejor si hubieras dejado tu pregunta tal como estaba, y hubieras enviado una respuesta. – Marcin
* Puede * publicar una pregunta y responderla usted mismo, pero mantenga las preguntas y respuestas separadas. Ver http://meta.stackexchange.com/questions/17463/can-i-answer-my-own-questions-even-those-where-i-knew-the-answer-before-asking – delnan
Creo que olvidó una '@ classmethod' en la clase' Base'. –