Python 捕获;函数调用前/后“;类中所有函数的事件

Python 捕获;函数调用前/后“;类中所有函数的事件,python,python-3.x,decorator,python-decorators,Python,Python 3.x,Decorator,Python Decorators,是否有可能捕获类中所有函数的“函数调用前/后”事件,而不装饰这些函数?可能是某个班级装饰师?换句话说,对于这样的代码,我希望得到以下输出: class Foo: def func1(): print('1') def func2(): print('2') c = Foo() c.func1() c.func2() # Output I would like to get: # func1 called # 1 # func1 finishe

是否有可能捕获类中所有函数的“函数调用前/后”事件,而不装饰这些函数?可能是某个班级装饰师?换句话说,对于这样的代码,我希望得到以下输出:

class Foo:
    def func1():
        print('1')

    def func2():
        print('2')

c = Foo()
c.func1()
c.func2()

# Output I would like to get:
# func1 called
# 1
# func1 finished
# func2 called
# 2
# func2 finished

我不需要它来追踪。在使用异步函数的课堂上,我需要知道在其他函数完成之前是否调用了某些函数。

是的,您可以编写一个类装饰器;以下内容将允许您装饰类中的每个函数:

def decorate_all_functions(function_decorator):
    def decorator(cls):
        for name, obj in vars(cls).items():
            if callable(obj):
                try:
                    obj = obj.__func__  # unwrap Python 2 unbound method
                except AttributeError:
                    pass  # not needed in Python 3
                setattr(cls, name, function_decorator(obj))
        return cls
    return decorator
上面的类装饰器将给定的函数装饰器应用于类上的所有可调用项

假设您有一个decorator,该decorator在以下时间前后打印被调用函数的名称:

from functools import wraps

def print_on_call(func):
    @wraps(func)
    def wrapper(*args, **kw):
        print('{} called'.format(func.__name__))
        try:
            res = func(*args, **kw)
        finally:
            print('{} finished'.format(func.__name__))
        return res
    return wrapper
然后类装饰器可以应用于:

@decorate_all_functions(print_on_call)
class Foo:
    def func1(self):
        print('1')

    def func2(self):
        print('2')
演示:


例如,输入打印语句。换句话说,我需要在类调用中的任何函数之前/之后调用某些函数。即使我将在类中添加新函数。
>>> @decorate_all_functions(print_on_call)
... class Foo:
...     def func1(self):
...         print('1')
...     def func2(self):
...         print('2')
... 
>>> c = Foo()
>>> c.func1()
func1 called
1
func1 finished
>>> c.func2()
func2 called
2
func2 finished