functools.partial与普通的Python函数

时间:2014-07-02 13:33:21

标签: python lambda partial-application

我正在学习偏见以及何时使用它们。在这个关于partials vs lambdas的页面中,接受的答案解释了partials优于lambdas的一个优点是,partials具有对内省有用的属性。所以我们可以使用partials来执行以下操作:

import functools
f = functools.partial(int, base=2)
print f.args, f.func, f.keywords

((), int, {'base': 2})

事实上,我们不能用lambdas

来做到这一点
h = lambda x : int(x,base=2)
print h.args, h.func, h.keywords

AttributeError: 'function' object has no attribute 'args'

但实际上,我们不能用"正常" Python的功能是:

def g(x) :
  return int(x,base=2) 
print g.args, g.func, g.keywords

AttributeError: 'function' object has no attribute 'args'

为什么partials比普通的Python函数有更多的功能?这种设计的目的是什么?对于正常的函数,内省被认为是无用的吗?

1 个答案:

答案 0 :(得分:5)

函数 do 包含有关它们接受的参数的信息。属性名称和数据结构比开发人员更多地针对解释器,但信息。您必须反省.func_defaults.func_code.co_varnames结构(以及其他一些结构)来查找这些详细信息。

使用inspect.getargspec() function可以更简单地提取信息:

>>> import inspect
>>> h = lambda x : int(x,base=2)
>>> inspect.getargspec(h)
ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

请注意,lambda生成与def funcname():函数语句生成的完全相同的对象类型。

这个没有给你的是什么参数将被传递到包装函数。这是因为函数具有更通用的用途,而functools.partial()是专用的,因此可以轻松地为您提供该信息。因此,partial告诉您base=2将传递到int(),但lambda只能告诉您收到参数{ {1}}。

因此,虽然x对象可以告诉您哪些参数将被传递到哪个函数,但functools.partial()对象只能告诉您它接收的参数,因为它是构成函数 body 以执行对包装函数的调用的(可能更复杂的)表达式。而这忽略了所有那些根本不会调用其他功能的功能。