在decorators中命名关键字?

2024-09-26 22:53:04 发布

您现在位置:Python中文网/ 问答频道 /正文

在我去看别人的代码之前,我一直在试图写我自己版本的回忆录装饰器。老实说,这更像是一种有趣的锻炼。然而,在玩的过程中,我发现我不能做一些我想做的装饰。在

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

@addValue( val=4 )
def computeSomething( x ):
    #function gets defined

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

^{pr2}$

为什么我不能用这种方式对decorator使用关键字参数?我做错了什么?你能告诉我该怎么做吗?在


Tags: 代码版本addreturn过程deffunction装饰
3条回答

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

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

当您编写^{cd1>}时,^{cd2>}的值直接用作装饰器。但是,当您编写^{cd3>}时,首先^{cd4>}通过调用addValue函数来计算。然后,结果被用作装饰器。

您希望部分应用函数addValue-给出val参数,而不是{}。通常有两种方法:

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

另一种方法是functools.partial对象。它使用对函数的检查来确定函数需要运行的参数(在您的例子中是funcval)。您可以在创建partial时添加额外的参数,一旦调用partial,它将使用所有给定的额外参数。在

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

对于这个部分应用问题,Partials通常是一个简单得多的解决方案,尤其是对于多个参数。在

具有任何种类的参数的装饰器,命名为/关键字的参数,未命名的/位置的参数,或每种参数中的某些参数,你@name行上调用而不是仅仅提及则需要一个两个级别的嵌套(而您刚才提到的decorator只有一个嵌套级别)。如果你想在@行中调用它们的话,这甚至适用于无参数的双嵌套修饰符

def double():
  def middling():
    def inner(f):
      return f
    return inner
  return middling

你会把这个当作

^{pr2}$

注意括号(在本例中为空,因为不需要也不需要参数):它们表示您在调用调用double,它返回middling,它修饰whatever。在

一旦您了解了“调用”和“仅提及”之间的区别,添加(例如可选)命名参数并不难:

def doublet(foo=23):
  def middling():
    def inner(f):
      return f
    return inner
  return middling

可用作:

@doublet()
def whatever ...

或作为:

@doublet(foo=45)
def whatever ...

或等同于:

@doublet(45)
def whatever ...

相关问题 更多 >

    热门问题