Python装饰器多次调用函数

标签 python python-decorators

有没有办法用装饰器多次调用一个函数?

这是我的代码:

def call_func(**case):
    def decorator(func):
        def wrapped_function(*args, **kwargs):
            return func(*args, **case)
        return wrapped_function
    return decorator

@call_func(p=1, o=2)
@call_func(p=3, o=4)
@call_func(p=5, o=6)
def some_func(p, o):
    print(p, o)

some_func()

输出是:

(5, 6)

但我想要:

(1, 2)
(3, 4)
(5, 6)

这可能吗?而且,这是 Pythonic 吗?

最佳答案

import functools
def call_func(cache={}, **case):
    def decorator(func):
        funcname = func.__name__
        if funcname not in cache:
            # save the original function
            cache[funcname] = func
        @functools.wraps(func)
        def wrapped_function(**kwargs):
            if cache[funcname] != func:
                cache[funcname](**case)
            func(**case)
        return wrapped_function
    return decorator

@call_func(p=1, o=2)
@call_func(p=3, o=4)
@call_func(p=5, o=6)
def some_func(p, o):
    print(p, o)

some_func()

产量

(1, 2)
(3, 4)
(5, 6)
<小时/>

您的 call_func 装饰器已接近创建所需的函数调用链。 考虑一下:

def call_func(**case):
    def decorator(func):
        def wrapped_function(**kwargs):
            print(case)
            func(**case)
        return wrapped_function
    return decorator

@call_func(p=1, o=2)
@call_func(p=3, o=4)
@call_func(p=5, o=6)
def some_func(p, o):
    print(p, o)

some_func()

产量

{'p': 1, 'o': 2}
{'p': 3, 'o': 4}
{'p': 5, 'o': 6}
(5, 6)

因此,wrapped_functions 显然是按正确的顺序调用的,并且具有 case 所需的值。唯一的问题是我们想要在每个阶段调用原始函数some_func

我们需要以某种方式让每个wrapped_function访问原始some_func

我们可以通过给call_func一个缓存来实现这一点,该缓存记录它第一次看到某个特定名称的函数的时间。这就是目的

def call_func(cache={}, **case):
    def decorator(func):
        funcname = func.__name__
        if funcname not in cache:
            # save the original function
            cache[funcname] = func

关于Python装饰器多次调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28767826/

相关文章:

python - 使用 python scipy 将 Gamma 分布拟合到数据

python - 如何创建除一组给定值之外的随机序列

python - 在类装饰器中重用全局函数

python - Python 中用参数修饰是什么意思?

python - 为什么 AWS Lambda 在将函数传递给装饰器时会超时?

python - 如何装饰 Django 中的管理操作,action.__name__ 用作字典键?

python - 如何使用装饰器类来装饰实例方法?

python - 识别 pandas 中具有稀疏 nan 的时间序列中的数据组

python - 在 Python 中实现位交换 hack

python - Pytest:如何使用从 fixture 返回的列表参数化测试?