Hay algunas formas interesantes de ejecutar un método antes de cada método en una clase en preguntas como Python: ¿Hacer algo para cualquier método de una clase?
Sin embargo esa solución no nos deja pasar argumentos.
Hay una solución decorativa en los eventos de “Llamada de función antes / después” de Catch para todas las funciones en clase, pero no quiero tener que volver y decorar todas mis clases.
¿Hay alguna manera de ejecutar una operación previa / posterior que dependa de los argumentos que se aprueban para cada invocación del método de un objeto?
Ejemplo:
class Stuff(object): def do_stuff(self, stuff): print(stuff) a = Stuff() a.do_stuff('foobar') "Pre operation for foobar" "foobar" "Post operation for foobar"
Así que me di cuenta después de mucha experimentación.
Básicamente, en la metaclase ‘ __new__
puede iterar a través de cada método en el espacio de nombres de la clase y cambiar cada método en la clase que se está creando con una nueva versión que ejecuta la lógica anterior, la función en sí misma y la lógica posterior. Aquí hay una muestra:
class TestMeta(type): def __new__(mcl, name, bases, nmspc): def replaced_fnc(fn): def new_test(*args, **kwargs): # do whatever for before function run result = fn(*args, **kwargs) # do whatever for after function run return result return new_test for i in nmspc: if callable(nmspc[i]): nmspc[i] = replaced_fnc(nmspc[i]) return (super(TestMeta, mcl).__new__(mcl, name, bases, nmspc))
Tenga en cuenta que si usa este código tal como está, también ejecutará la operación pre / post para init y otras funciones integradas.