Я хочу создать метакласс, который будет украшать каждую функцию с помощью декоратора трассировки.
Итак, я получил это:
from functools import wraps
from inspect import getfile
from arrow import now
def trace(f):
@wraps(f)
def wrapper(*args, **kwargs):
print(
'{timestamp} - {file} - {function} - CALL *{args} ** {kwargs}'.format(timestamp=now().isoformat(sep=' '),
file=getfile(f),
function=f.__name__, args=args[1:],
kwargs=kwargs))
result = f(*args, **kwargs)
print(
'{timestamp} - {file} - {function} - RESULT {result}'.format(timestamp=now().isoformat(sep=' '),
file=getfile(f),
function=f.__name__,
result=result))
return result
return wrapper
class TraceLogger(type):
def __new__(mcs, name, bases, dct):
for attr in dct:
value = dct[attr]
if callable(value):
dct[attr] = trace(value)
return super(TraceLogger, mcs).__new__(mcs, name, bases, dct)
class ExampleClass(object):
__metaclass__ = TraceLogger
def foo(self):
print('foo')
@staticmethod
def bar():
print('bar')
example = ExampleClass()
example.foo()
example.bar()
Трассировка работает для любых нестатических функций, поскольку статические методы не могут быть вызваны.Как можно развернуть staticmethod, а затем обернуть его два раза в new metclass, например:
dct[attr] = staticmethod(trace(value))