Functional Python Programming

(Wang) #1
Chapter 11

We almost always want to use the functools.wraps() function to assure that the
decorated function retains the attributes of the original function. Copying the
name
, and doc attributes, for example, assures that the resulting decorated
function has the name and docstring of the original function.


The resulting composite function, called null_wrapper() function in the definition
of the decorator, is also a kind of higher-order function that combines the original
function, the function() function, in an expression that preserves the None values.
The original function is not an explicit argument; it is a free variable that will get its
value from the context in which the wrapper() function is defined.


The decorator function's return value will return the newly minted function. It's
important that decorators only return functions, and not attempt any processing of
data. Decorators are meta-programming: a code that creates a code. The wrapper()
function, however, will be used to process the real data.


We can apply our @nullable decorator to create a composite function as follows:


nlog = nullable(math.log)


We now have a function, nlog(), which is a null-aware version of the math.log()
function. We can use our composite, nlog() function, as follows:





some_data = [10, 100, None, 50, 60]








scaled = map(nlog, some_data)








list(scaled)





[2.302585092994046, 4.605170185988092, None, 3.912023005428146,
4.0943445622221]


We've applied the function to a collection of data values. The None value politely
leads to a None result. There was no exception processing involved.


This example isn't really suitable for unit testing. We'll need
to round the values for testing purposes. For this, we'll need
a null-aware round() function too.

Here's how we can create a null-aware rounding function using decorator notation:


@nullable


def nround4(x):


return round(x,4)


This function is a partial application of the round() function, wrapped to be
null-aware. In some respects, this is a relatively sophisticated bit of functional
programming that's readily available to Python programmers.

Free download pdf