我从一个我不理解的人那里得到了一段代码:
def __init__(self, func):
self.func = func
wraps(func)(self)
我已经多次见过像wraps(func)(self)
这样的东西,但从未见过它。怎么有一个带参数的函数,然后是另一个(var)
之后呢?这是什么意思呢?谢谢
答案 0 :(得分:16)
Python中的函数是first-class objects。
如果您只输入了没有括号的函数的名称,毫无疑问在命令行中会遇到这种情况。
In [2]: a
Out[2]: <function __main__.a>
当你看到a(b)(c)
时,它是一种链接方法:
a
被定义为返回另一个函数。a(b)
调用a
并返回该引用(对可调用函数)a(b)(c)
调用a
以c
作为参数返回的任何函数。这相当于以下内容:
new_func = a(b)
new_func(c)
一个例子:
In [1]: def multiply_by(x):
...: def multiply_by_x(y):
...: return x * y
...: return multiply_by_x # notice no parens
...:
In [2]: multiply_by(10)
Out[2]: <function __main__.multiply_by_x>
请注意,当您调用此方法时,您将获得功能对象。 (这就是我所说的&#34;对函数&#34;等等的引用。)
In [3]: multiply_by(10)(5)
Out[3]: 50
您以{5}为参数调用multiply_by()
返回的函数,它与执行完全相同:
In [4]: multiply_by_10 = multiply_by(10)
In [5]: multiply_by_10(4)
Out[5]: 40
In [6]: multiply_by_10(8)
Out[6]: 80
从这个例子中可以看出,关于这样做很酷的事情是,现在你的multiply_by
函数是一个函数的工厂,它可以乘以某些东西。在上面,我们创建了multiply_by_10
,显然,它将您提供的数据乘以10.我们可以轻松地做到:
In [7]: multiply_by_5 = multiply_by(5)
并且有一个乘以5的函数。这显然非常有用。顺便说一句,它也是Python decorators的工作方式。
感谢@MarkusMeskanen在评论中指出了一种方法,让我的愚蠢的例子成为一个更酷的例子!
另见:
答案 1 :(得分:3)
关键是wraps()
将一个函数作为参数并返回一个函数,可能会添加一些额外的好处,就像decorator function那样。
如果您要print(wraps(func))
,您应该看到将对象标识为函数的输出。
因此wraps(func)(self)
可以改写为
wrapped_func = wraps(func)
wrapped_func(self)
对某些人来说看起来更“正常”。
答案 2 :(得分:2)
你的情况是函数wrap
返回一个可调用的函数,即函数或类或任何实现__call__
方法的对象。所以只是要了解一下这个例子:
def wraps(arg):
def decor(func):
print(arg)
return func
return decor
这是一个典型的装饰器,这意味着您可以执行以下操作:
@wrap('some arg')
def func(a):
print(a)
所以这里发生的是以下内容:
wrap
调用some arg
函数。正如你可以在内部包装中我们定义了另一个decor
函数,该函数被返回wrap
函数返回的任何内容,即在返回的对象上调用__call__
方法,其中参数是要装饰的函数。在这种情况下,我们有decor(func)
。decor
函数只打印arg
(在我们的例子中为'some arg'
)的值,并返回func
。注意:这只是一次!
func('hello1')
func('hello2')
...您将获得以下输出
some arg
hello1
hello2