Co[de]mmunications

Programming and ramblings on software engineering.

Python Functors

The task is to multiply items in some iterable by three.

multipled = [3 * s for s in series]

One list comprehension later, the task is complete.

Next, we find out that we need to count how many multiplications are performed. len() is forbidden, because we are dealing with iterators (and inevitably the itertools module). One solution is to create a CallCounting class that wraps callables.

class CallCounting(object):

    def __init__(self, func):
        self.count = 0
        self.func = func

    def __call__(self, *args, **kwargs):
        self.count += 1
        return self.func(*args, **kwargs)

timesthree = CallCounting(lambda x: 3 * x)
multipled = [timesthree(n) for n in series]

print "%d calls" % timesthree.count

This is efficient as well as readable. The main action is to multiply items. We keep a call count just for bookkeeping. Compare with

calls = 0
multipled = []
for n in series:
    calls += 1
    multipled.append(3 * n)

print "%d calls" % calls

that is both ugly and inefficient.

Comments