简体   繁体   中英

functools.partial vs normal Python function

I am learning about partials and when to use them. In this page about partials vs lambdas , the accepted answer explains that one of the advantages of partials over lambdas , is that partials have attributes useful for introspection. So we can do the following with partials:

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

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

Indeed, we cannot do that with lambdas :

h = lambda x : int(x,base=2)
print h.args, h.func, h.keywords

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

But actually, we cannot do that with "normal" Python functions either:

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

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

Why do partials have more functionalities than normal Python functions? What is the intent of such a design? Is introspection considered useless for normal functions?

Functions do have information about what arguments they accept. The attribute names and data structures are aimed at the interpreter more than the developer, but the info is there. You'd have to introspect the .func_defaults and .func_code.co_varnames structures (and a few more besides) to find those details.

Using the inspect.getargspec() function makes extracting the info a little more straightforward:

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

Note that a lambda produces the exact same object type as a def funcname(): function statement produces.

What this doesn't give you, is what arguments are going to be passed into the wrapped function . That's because a function has a more generic use, while functools.partial() is specialised and thus can easily provide you with that information. As such, the partial tells you that base=2 will be passed into int() , but the lambda can only tell you it receives an argument x .

So, while a functools.partial() object can tell you what arguments are going to be passed into what function, a function object can only tell you what arguments it receives, as it is the job of the (potentially much more complex) expressions that make up the function body to do the call to a wrapped function. And that is ignoring all those functions that don't call other functions at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM