una programacion poo otra orientada objetos metodos metodo llamar instancia importar como clases clase python

programacion - Cómo decorar los métodos de clase de Python: ¿cómo le paso la instancia al decorador?



poo python 3 (4)

La respuesta de Alex es suficiente cuando una función es suficiente. Sin embargo, cuando necesite una clase, puede hacer que funcione agregando el siguiente método a la clase decoradora.

def __get__(self, obj, objtype): """Support instance methods.""" import functools return functools.partial(self.__call__, obj)

Para entender esto necesitas entender el protocolo descriptor. El protocolo descriptor es el mecanismo para vincular una cosa a una instancia. Consiste en __ obtener __, __ establecer __ y __ eliminar __, que se llaman cuando el objeto se obtiene, configura o elimina del diccionario de instancias.

En este caso, cuando la cosa se obtiene de la instancia, estamos vinculando el primer argumento de su método __ call __ a la instancia, utilizando parcial. Esto se hace automáticamente para las funciones miembro cuando se construye la clase, pero para una función miembro sintética como esta necesitamos hacerlo explícitamente.

Esto es Python 2.5, y también es GAE , no es que importe.

tengo el siguiente código. Estoy decorando el método foo () en la barra, usando la clase dec_check como decorador.

class dec_check(object): def __init__(self, f): self.func = f def __call__(self): print ''In dec_check.__init__()'' self.func() class bar(object): @dec_check def foo(self): print ''In bar.foo()'' b = bar() b.foo()

Al ejecutar esto esperaba ver:

In dec_check.__init__() In bar.foo()

Pero estoy obteniendo " TypeError: foo() takes exactly 1 argument (0 given) " como .foo() , al ser un método de objeto, toma self como argumento. Supongo que el problema es que la instancia de la bar no existe realmente cuando ejecuto el código de decoración.

Entonces, ¿cómo paso una instancia de bar a la clase de decorador?



Si quieres escribir el decorador como una clase puedes hacerlo:

from functools import update_wrapper, partial class MyDecorator(object): def __init__(self, func): update_wrapper(self, func) self.func = func def __get__(self, obj, objtype): """Support instance methods.""" return functools.partial(self.__call__, obj) def __call__(self, obj, *args, **kwargs): print(''Logic here'') return self.func(obj, *args, **kwargs) my_decorator = MyDecorator class MyClass(object): @my_decorator def my_method(self): pass


__get__ convertir al decorador en un descriptor , ya sea asegurándose de que su (meta) clase tenga un método __get__ o, mucho más sencillo, utilizando una función decoradora en lugar de una clase decoradora (ya que las funciones ya son descriptores). P.ej:

def dec_check(f): def deco(self): print ''In deco'' f(self) return deco class bar(object): @dec_check def foo(self): print ''in bar.foo'' b = bar() b.foo()

esto imprime

In deco in bar.foo

como se desee.