oyxpiukg
oyxpiukg

Reputation: 3

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?

Upvotes: 0

Views: 209

Answers (3)

Blckknght
Blckknght

Reputation: 104762

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").

Upvotes: 1

Cory Kramer
Cory Kramer

Reputation: 117951

I don't really see what you're solving. You're just changing your methods from

'abc'.upper()

to

upper('abc')

It doesn't really gain you anything, in fact it's a little less readable. If you're using the lambda's to pass into other methods as key you can just do something like

l = ['ab', 'Aa', 'ca']
sorted(l, key = str.upper)

Note that I can just call str.upper without having to define a lambda

Upvotes: 4

Dr. Jan-Philip Gehrcke
Dr. Jan-Philip Gehrcke

Reputation: 35796

How can I avoid or at least minimize such boilerplate?

Just do not use it! Or, more specifically:

  • Use c.upper() instead of upper(c)
  • Use c.lower() instead of lower(c)
  • Use a.foo(b) instead of foo(a, b)

Upvotes: 2

Related Questions