什么是python中的函数(var1)(var2)

时间:2015-08-27 20:31:10

标签: python

我从一个我不理解的人那里得到了一段代码:

def __init__(self, func):
        self.func = func
        wraps(func)(self)

我已经多次见过像wraps(func)(self)这样的东西,但从未见过它。怎么有一个带参数的函数,然后是另一个(var)之后呢?这是什么意思呢?谢谢

3 个答案:

答案 0 :(得分:16)

Python中的函数是first-class objects

如果您只输入了没有括号的函数的名称,毫无疑问在命令行中会遇到这种情况。

In [2]: a
Out[2]: <function __main__.a>

当你看到a(b)(c)时,它是一种链接方法:

  • 函数a被定义为返回另一个函数
  • a(b)调用a并返回该引用(对可调用函数)
  • a(b)(c)调用ac作为参数返回的任何函数。

这相当于以下内容:

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)

所以这里发生的是以下内容:

  1. 首先使用参数值wrap调用some arg函数。正如你可以在内部包装中我们定义了另一个decor函数,该函数被返回
  2. 正在调用从wrap函数返回的任何内容,即在返回的对象上调用__call__方法,其中参数是要装饰的函数。在这种情况下,我们有decor(func)
  3. 我们的decor函数只打印arg(在我们的例子中为'some arg')的值,并返回func
  4. 注意:这只是一次!

    func('hello1')
    func('hello2')
    

    ...您将获得以下输出

    some arg
    hello1
    hello2