简体   繁体   English

使用任意数量的函数作为参数并返回函数组成的Python装饰器

[英]Python decorator that takes arbitrary number of functions as arguments and returns composition of functions

I am trying to write a decorator that takes an arbitrary number of functions as positional arguments and then composes these functions with the function that is being decorated. 我正在尝试编写一个装饰器,该装饰器将任意数量的函数用作位置参数,然后将这些函数与正在装饰的函数组成。

Conceptually, I am trying to do this: 从概念上讲,我正在尝试这样做:

@format(f1, f2, f3)
def f0(param):
    return value

f0(arg) should evaluate to f3(f2(f1(f0(arg)))) f0(arg)应该评估为f3(f2(f1(f0(arg))))

Here is a simple example I have been working on to illustrate the concept. 这是我一直在努力说明这个概念的一个简单示例。

def lc(s):
    s = s.lower()
    return s

def punc(s):
    if s[-1] != ".":
        s = s + "."
        return s
    else:
        return s

def cap(s):
    s = s[0].upper() + s[1:]
    return s

def format(*args):
    def wrapper(func, *a):
        for f in args:
            func = f(func)
        return func
    return wrapper

@format(lc, punc, cap)
def example_func(param):
    return param

What I'm expecting is this: 我期望的是:

f0("MY TEST STRING")

My test string.

I'm getting the following error message: 我收到以下错误消息:

AttributeError: 'function' object has no attribute 'lower'

There may be an easier way to do this, such as pass the functions directly into the original and not use a decorator, but I am looking for a solution that specifically uses a decorator in this way. 可能有一种更简单的方法来执行此操作,例如将函数直接传递到原始函数中而不使用装饰器,但是我正在寻找一种以这种方式专门使用装饰器的解决方案。 Thank you. 谢谢。

You need to use the "decorator-with arguments" pattern, so like this: 您需要使用“带有参数的装饰器”模式,如下所示:

def format(*fs):
    def deco(f):
        def wrapper(x):
            val = f(x)
            for func in fs:
                val = func(val)
            return val
        return wrapper
    return deco

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM