Decorator Design Techniques
A parameterized decorator has three parts and they are as follows:
- The overall decorator. This defines and returns the abstract decorator.
In this case, the cr_decorator is an abstract decorator. This has a free
variable, char_list, that comes from the initial decorator. - The abstract decorator. In this case, the cr_decorator decorator will have
its free variable, char_list, bound so that it can be applied to a function. - The decorating wrapper. In this example, the wrap_char_remove function
will replace the wrapped function. Because of the @wraps decorator,
the name (and other attributes) will be replaced with the name of the
function being wrapped.
We can use this decorator to create conversion functions as follows:
@bad_char_remove("$", ",")
def currency(text, **kw):
return Decimal(text, **kw)
We've used our decorator to wrap a currency() function. The essential feature
of the currency() function is a reference to the decimal.Decimal constructor.
This currency() function will now handle some variant data formats:
currency("13")
Decimal('13')
currency("$3.14")
Decimal('3.14')
currency("$1,701.00")
Decimal('1701.00')
We can now process input data using a relatively simple map(currency, row)
method to convert source data from strings to usable Decimal values. The try:/
except: error-handling has been isolated to a function that we've used to build a
composite conversion function.
We can use a similar design to create Null-tolerant functions. These functions would
use a similar try:/except: wrapper, but would simply return the None values.