Multi-Line Lambdas in Python Using the With Statement
billmill.org
billmill.org
Doesn't like this
def handle_click(self):
foo = self.flim()
if foo:
self.flam(foo)
onClick(handle_click)
And thinks this mess is better with onClick():
def _(self):
foo = self.flim()
if foo:
self.flam()
My problems with 2nd include 1) it's ugly, convulted and I'd argue misusing with, 2) by no longer having a name for flimflamfunc you loose documentation, 3) hard to reuse flimflamfunc, 4) hard to decorate, mock, dynamically replace flimflamfunc.Author's main dislike about first code block is "we're required to define the function body before the place where it will be actually used." Which I think is preferable but accept that's my opinion. They're ways to solve that which are easier, cleaner, and more pythonic than author's proposed solution.
def callback(onFoo):
def inner(func):
onFoo(func)
return func
return inner
@callback(onClick)
def handle_click(self):
pass
There might be good reasons for multi-line lambdas, but I don't see any presented here. And if we assume multi-line lambdas are awesome, this is not an acceptable implimentation.1) Agreed. I'd never want to see this technique in my programs.
2) What stops you from giving it a name?
3) Putting code inline is presumably a conscious decision not to extract it into a wider scope.
4) How's it hard to decorate? For mocking and dynamically replacing, again, that goes for any inline code. Objections 3 and 4 have to argue against functions appearing in non-global scopes in general.
with bmap([1,2,3]) as foo:
def _(x):
return (float(x) + 1) / 2
print foo # [1.0, 1.5, 2.0]
could be done with decorators: def flip(f, x): # from Haskell's standard library
return lambda y: f(y, x)
@flip(map, [1,2,3])
def result(x):
return (float(x) + 1) / 2
print result # [1.0, 1.5, 2.0]
though the way 'result' is bound is, er, unconventional.