我最近决定学习Python装饰器,并学习了this howto。尤其是“将参数传递给decorators”部分下的示例。我要做的是(1)decorator函数应该接受一些参数(degarg),(2)处理它们,以及(3)使用参数调用修饰函数(funarg)。我知道如何给decorator提供参数,但是我还没有看到任何例子,其中decorated函数的参数只在decorator中可用。当我调用decorated函数时,我完全不确定应该使用什么参数,因为它的参数将在decorator函数中计算。下面是一个基于上述操作方法的示例:
def dec(decarg):
def _dec(fun):
funarg = decarg + 7
def _fun(funarg):
return fun(funarg)
return _fun
return _dec
def main(mainarg):
decarg = mainarg + 2
@dec(decarg)
def fun1(funarg):
return funarg + 3
return fun1(decarg)
main(1)
它返回6,而我预期是13。我希望参数在main()
中递增2,在_dec()
中增加7,这将把这个变量传递给修饰函数,后者向它添加3。在
之后,我阅读了this和{a3}howtos,并使用他们的方法创建了一个与我想象的一样的示例:
^{pr2}$所以现在我的问题是:如何对第一种表示法做同样的处理,其中decorator不是一个类,而是一个函数?请您澄清一下,它是如何工作的,哪些参数和何时被传递给__init__()
,以及给装饰器的__call__()
方法什么?在
原因是在考虑了decorator如何转换函数以及函数本身就是Python中的对象之后。在
我们从后者开始。在
函数是对象:
当我们考虑函数名后两对括号的含义时,这是立即的。考虑这个简单的例子(Python3):
这里“func”返回一个函数对象“func2”,因此您可以使用:
^{pr2}$您可以将此视为先调用
并将“(10)”应用于结果对象,即函数!所以你有:
现在既然定义了“x”和“y”,那么“func2”可以将最终值返回到“result”。在
记住,这是可能的,因为函数本身就是对象,而且“func”返回的是函数对象
并且不是它的结果(它不是单独调用函数)
简言之,这意味着对于包装函数,第二组参数用于内部函数(如果包装器返回内部函数对象)。在
装饰者:
在您的示例中,“main”在最后一行中调用“fun1”
因为装修工
实际上,你可以把“fun1”想象成:
因此,“main”中的最后一行相当于:
根据前面的解释,找到问题应该很简单!在
dec(decarg)
被执行并返回一个“_dec”函数对象;注意这个“decarg”是在第一个括号中传递的对象,因此在decorator中也是这样。在_dec(fun1)
执行并返回一个“\u fun”函数对象。在_fun(decarg)
执行并使用return语句调用fun1(decargs),这将在fun1(3)中正确转换,这是您得到的结果;请注意,这个“decarg”是在第三个括号中传递的,因此当您在main中调用“fun1”时也是如此。在你不能得到13,因为你没有调用“fun1”的结果
作为参数,而是使用从main传递给“\u fun”的“degarg”作为位置参数(funarg=decarg)来调用它。在
不管怎样,我必须感谢您提出这个问题,因为我正在寻找一种简单的方法,只在调用函数时才将参数传递给decorator,这非常有效。在
下面是另一个可能有帮助的示例:
好的,这里有一个简单的解释:
一个简单的装饰器(没有参数)是一个函数,它接受一个函数作为参数,并返回另一个函数来代替原来的函数
接受参数的decorator是一个接受该参数并返回一个简单decorator的函数
在这里,您可以构建一个简单的decorator,将7添加到修饰函数的参数中:
您可以这样使用它:
^{pr2}$它按预期返回13。在
但您可以轻松地构建一个参数化的decorator,它将添加一个任意值,但添加一个用于处理参数的级别:
然后你就可以那样用了
仍然返回13
相关问题 更多 >
编程相关推荐