DekGenius.com
[ Team LiB ] Previous Section Next Section

14.2 Applying Functions to Arguments

Some programs need to call arbitrary functions in a generic fashion, without knowing their names or arguments ahead of time. We'll see examples of where this can be useful later, but by way of introduction, both the apply built-in function, and the special call syntax, do the job.

14.2.1 The apply Built-in

You can call generated functions by passing them as arguments to apply, along with a tuple of arguments:

>>> def func(x, y, z): return x + y + z
...
>>> apply(func, (2, 3, 4))
9
>>> f = lambda x, y, z: x + y + z
>>> apply(f, (2, 3, 4))
9

The function apply simply calls the passed-in function in the first argument, matching the passed-in arguments tuple to the function's expected arguments. Since the arguments list is passed in as a tuple (i.e., a data structure), it can be built at runtime by a program.[3]

[3] Be careful not to confuse apply with map, the topic of the next section. apply runs a single function call, passing arguments to the function object just once. map calls a function many times instead, for each item in a sequence.

The real power of apply is that it doesn't need to know how many arguments a function is being called with; for example, you can use if logic to select from a set of functions and argument lists, and use apply to call any:

if <test>:
    action, args = func1, (1,)
else:
    action, args = func2, (1, 2, 3)
. . . 
apply(action, args)

More generally, apply is useful any time you cannot predict the arguments list ahead of time. If your user selects an arbitrary function via a user interface, for instance, you may be unable to hardcode a function call when writing your script. Simply build up the arguments list with tuple operations and call indirectly through apply:

>>> args = (2,3) + (4,)
>>> args
(2, 3, 4)
>>> apply(func, args)
9
14.2.1.1 Passing keyword arguments

The apply call also supports an optional third argument, where you can pass in a dictionary that represents keyword arguments to be passed to the function:

>>> def echo(*args, **kwargs): print args, kwargs

>>> echo(1, 2, a=3, b=4)
(1, 2) {'a': 3, 'b': 4}

This allows us to construct both positional and keyword arguments, at runtime:

>>> pargs = (1, 2)
>>> kargs = {'a':3, 'b':4}
>>> apply(echo, pargs, kargs)
(1, 2) {'a': 3, 'b': 4}

14.2.2 Apply-Like Call Syntax

Python also allows you to accomplish the same effect as an apply call with special syntax at the call, which mirrors the arbitrary arguments syntax in def headers that we met in Chapter 13. For example, assuming the names of this example are still as assigned earlier:

>>> apply(func, args)              # Traditional: tuple
9
>>> func(*args)                    # New apply-like syntax
9
>>> echo(*pargs, **kargs)          # Keyword dictionaries too
(1, 2) {'a': 3, 'b': 4}

>>> echo(0, *pargs, **kargs)       # Normal, *tuple, **dictionary
(0, 1, 2) {'a': 3, 'b': 4}

This special call syntax is newer than the apply function. There is no obvious advantage of the syntax over an explicit apply call, apart from its symmetry with def headers, and a few less keystrokes.

    [ Team LiB ] Previous Section Next Section