Functions, Iterators, and Generators
To make this more consistent, we can consider defining our own prefix functions for
the string method functions, as follows:
def replace(data, a, b):
return data.replace(a,b)
This can allow us to use Decimal(replace(replace(text, "$", ""), ",", ""))
with consistent-looking prefix syntax. In this case, we simply rearrange the existing
argument values, allowing us an additional technique. We can do this for trivial
cases, such as the follows:
replace=str.replace
replace("$12.45","$","")
12.45
It's not clear if this kind of consistency is a significant improvement over the mixed
prefix and postfix notation. The issue with functions of multiple arguments is that
the arguments wind up in various places in the expression.
A slightly better approach might be to define a more meaningful prefix function to
strip punctuation, such as the following command snippet:
def remove( str, chars ):
if chars: return remove( str.replace(chars[0], ""), chars[1:] )
return str
This function will recursively remove each of the characters from the char variable.
We can use it as Decimal(remove(text, "$,")) to make the intent of our string
cleanup more clear.
Using tuples and namedtuples
Since Python tuples are immutable objects, they're another excellent example
of objects suitable for functional programming. A Python tuple has very few
method functions, so almost everything is done through functions using prefix
syntax. There are a number of use cases for tuples, particularly when working
with list-of-tuple, tuple-of-tuple and generator-of-tuple constructs.
Of course, namedtuples add an essential feature to a tuple: a name that we can use
instead of an index. We can exploit namedtuples to create objects that are accretions
of data. This allows us to write pure functions based on stateless objects, yet keep
data bound into tidy object-like packages.