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

Posted

技术标签:

【中文标题】捕获类中所有函数的“函数调用之前/之后”事件【英文标题】:Catch "before/after function call" events for all functions in class 【发布时间】:2014-11-07 20:20:14 【问题描述】:

是否有可能在不装饰每个函数的情况下?可能是一些班级装饰?换句话说,对于这样的代码,我想得到以下输出:

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

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

【问题讨论】:

输入打印报表? 例如。换句话说,我需要在类调用中的任何函数之前/之后调用一些函数。即使我会在课堂上添加新功能。 【参考方案1】:

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

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

上述类装饰器将给定的函数装饰器应用于类的所有可调用对象。

假设你有一个装饰器,它打印出被调用的函数的名称前后:

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

【讨论】:

以上是关于捕获类中所有函数的“函数调用之前/之后”事件的主要内容,如果未能解决你的问题,请参考以下文章

对成员函数的模糊调用以在 lambda 中捕获 this

js学习笔记26----事件冒泡,事件捕获

什么是钩子函数?钩子函数的使用。

AppDomain.AssemblyLoad 事件捕获事件处理程序中引发的所有异常

QML - 捕获子对象的所有 UI 事件

将 Node.js 流错误事件传播到异步等待样式代码