Friday, September 10, 2010

Anonymous function as default argument in methods

I was quite surprised by Python recently when I tried to use anonymous function that uses a class method (not classmethod) as a default argument for another class method and it worked. Example is worth thousands words so here it is:
class ListObject(object):
    items = ((1, 'one'), (2, 'two'), (3, 'three'))

    def get_num(self, item):
        return item[0]

    def get_text(self, item):
        return item[1]

    def get_list(self, fn=lambda s, i: ListObject.get_num(s, i)):
        return [fn(self, j) for j in self.items]

lo = ListObject()
print 'numbers:', lo.get_list()
print 'texts:', lo.get_list(ListObject.get_text)
print 'texts:', lo.get_list(lambda s, i: i[1])
print 'items:', lo.get_list(lambda s, i: i)
When you run this piece of code you get what you want:
numbers: [1, 2, 3]
texts: ['one', 'two', 'three']
texts: ['one', 'two', 'three']
items: [(1, 'one'), (2, 'two'), (3, 'three')]
By default, get_list method uses get_num method and apply it to all items. But you can supply your own fucntion to apply it on items.

Of course, this is very stupid example but it shows the principle. And this principle is quite handy for UI automation I am currently working on :-)