Reputation: 3
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
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
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
Reputation: 35796
How can I avoid or at least minimize such boilerplate?
Just do not use it! Or, more specifically:
c.upper()
instead of upper(c)
c.lower()
instead of lower(c)
a.foo(b)
instead of foo(a, b)
Upvotes: 2