Search code examples
pythonlambdaboilerplate

How to avoid repeating lambda boilerplate in python?


I find myself writing too many of these:

upper = lambda c   : c.upper()
lower = lambda c   : c.lower()
foo   = lambda a,b : a.foo(b)

How can I avoid or at least minimize such boilerplate?

Wasn't (or shouldn't be) there a PEP to allow passing/calling methods as normal procedures?


Solution

  • You can use unbound methods, rather than creating your own functions.

    In your first two examples, you'd probably want str.upper and str.lower. (If you need to support more than str, you could use operator.methodcaller("upper") or similar, but be aware that it is almost certainly a bad design decision to deal with both str and bytes objects with the same code!)

    Your third example is more complicated. If you only care about a single type of a object, then you'd specify it and it would work just like the str examples (e.g. A.foo). Similarly, if the value of b is constant and known ahead of time, you could use operator.methodcaller("foo", b) to get a callable that calls a.foo(b) for a given a value, but it doesn't help if b is also variable.

    If you don't know a's type or b in advance, you really do need to stick with a function. If you don't like how the lambda expression looks, you can use a regular def statement:

    def foo(a, b):
        return a.foo(b)
    

    If it's something you use often, you could write your own variation on methodcaller to produce the functions on demand:

    def my_methodcaller(method_name):
        def inner(obj, *args, **kwargs):
            return getattr(obj, method_name)(*args, **kwargs)
        return inner
    

    Then, you'd use foo = my_methodcaller("foo").