¿Cómo ejecutar un método antes / después de todas las llamadas de funciones de clase con argumentos pasados?

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.