Alternative to multi-line lambdas: Assign-anywhere def statements

Yawar Amin yawar.amin at gmail.com
Sun Jan 25 20:26:53 EST 2015


Hi Steven,

On Saturday, January 24, 2015 at 11:27:33 PM UTC-5, Steven D'Aprano
wrote:
> [...]
> > Doesn't the traceback tell us exactly where the lambda was called
> > from?
> 
> Yes (assuming the source code is available, which it may not be), but

If the source code is not available, then you're equally unable to debug
a lambda function and a named function.

> even so, which is easier?
> 
> "Oh, the exception occurred in myfunc"
> 
> versus
> 
> "Hmmm, the exception occurred in a lambda, lets see now, that was
> called by "f", but f might have called seven different lambdas, which
> [...]

True, Python's current traceback reporting doesn't tell us the exact
column number on which the exception occurred. So for example with this:

    print((lambda: 1)(), (lambda: 1 / 0)())

You will get the following traceback:

    Traceback (most recent call last):
      File "test.py", line 3, in <module>
        print((lambda: 1)(), (lambda: 1 / 0)())
      File "test.py", line 3, in <lambda>
        print((lambda: 1)(), (lambda: 1 / 0)())
    ZeroDivisionError: integer division or modulo by zero

So the problem is there are two lambdas in line 3, so you need to
examine them both to figure out which one caused the exception. The
simple solution to this is to just put the lambdas on different lines:

    print(
      (lambda: 1)(),
      (lambda: 1 / 0)()
    )

Now you get a blindingly obvious traceback:

    Traceback (most recent call last):
      File "test.py", line 5, in <module>
        (lambda: 1 / 0)()
      File "test.py", line 5, in <lambda>
        (lambda: 1 / 0)()
    ZeroDivisionError: integer division or modulo by zero


> Using lambda is trading off convenience when writing the code for ease
> of debugging the code when a problem occurs. Whether that trade-off is
> worthwhile or not depends on factors such as how likely the lambda is
> to have a bug, how many of them there are, and whether or not there is
> uncertainty as to which one is called from where.

I feel like this whole 'debugging' argument is a red herring, because
you can have _many_ different expressions in a line of code all of which
could have potentially caused an exception you're trying to debug. For
example, dispensing with the lambdas:

    print(1, 1 / 0)

Error:

    Traceback (most recent call last):
      File "test.py", line 3, in <module>
        print(1, 1 / 0)
    ZeroDivisionError: integer division or modulo by zero

Again, it all comes down to Python just not telling you precisely where
the error occurred, and instead only giving you the general vicinity.
Again, this can be fixed simply by just putting the expressions on
different lines.

Regards,

Yawar



More information about the Python-list mailing list