在装饰器中命名的关键字?

whe*_*ies 0 python decorator keyword named-parameters

在我去查看其他人的代码之前,我一直在尝试编写自己版本的memoizing装饰器.老实说,这更像是一种有趣的运动.然而,在玩耍的过程中,我发现我不能用装饰器做我想做的事情.

def addValue( func, val ):
    def add( x ):
        return func( x ) + val
    return add

@addValue( val=4 )
def computeSomething( x ):
    #function gets defined
Run Code Online (Sandbox Code Playgroud)

如果我想这样做,我必须这样做:

def addTwo( func ):
    return addValue( func, 2 )

@addTwo
def computeSomething( x ):
    #function gets defined
Run Code Online (Sandbox Code Playgroud)

为什么我不能以这种方式使用装饰器的关键字参数?我做错了什么,你能告诉我我应该怎么做吗?

int*_*jay 5

您需要定义一个返回装饰器的函数:

def addValue(val):
    def decorator(func):
        def add(x):
            return func(x) + val
        return add
    return decorator
Run Code Online (Sandbox Code Playgroud)

编写时@addTwo,值addTwo直接用作装饰器.但是,在编写时@addValue(4),首先addValue(4)通过调用addValue函数来计算.然后将结果用作装饰器.


Joc*_*zel 5

你想部分应用函数addValue- 给出val参数,但不是func.通常有两种方法可以做到这一点:

第一个被称为currying并在interjay的答案中使用:而不是具有两个参数f(a,b) -> res的函数,你编写第一个arg的函数,返回另一个函数,该函数接受第二个argg(a) -> (h(b) -> res)

另一种方式是一个functools.partial对象.它使用函数检查来确定函数需要运行的参数(在您的情况下为funcval).您可以在创建部分时添加额外的参数,一旦调用部分,它将使用给定的所有额外参数.

from functools import partial
@partial(addValue, val=2 ) # you can call this addTwo
def computeSomething( x ): 
    return x
Run Code Online (Sandbox Code Playgroud)

对于这个部分应用程序问题,Partials通常是一个更简单的解决方案,特别是对于多个参数.