Handling 3 operands in an expression without raising an exception

Jussi Piitulainen jpiitula at ling.helsinki.fi
Sun Sep 29 07:04:35 EDT 2013


Steven D'Aprano writes:

> On Sun, 29 Sep 2013 12:35:17 +0300, Jussi Piitulainen wrote:
> 
> > try:
> >   ...
> > except socket.gaierror as e:
> >   # watch out, a composition of bad advice (on demand) city, host = (
> >   ('city' in locals() or "blabla"),
> >                  ('host' in locals() or "blablabla") )
> 
> Bad advice, and buggy as well. 
> 
> py> city = "New New York"
> py> ('city' in locals() or "Blah blah")
> True
> 
> Oh man, can you imagine Nikos trying to debug that?

Thanks. Sorry. This hurts. I didn't mean it to be buggy.

Let's see. The task is to assign a default value to city and host, if
they haven't a value yet; on one line (which I take to mean one
statement); in an "except" block where we may not know which
assignment failed in the "try" block; without "if"; but "or" is
allowed.

But the logic I was trying to implement is

city, host = ( (city if 'city' in locals() else "default city"),
               (host if 'host' in locals() else "default host") )

which uses an "if". The old tricks of using "or" and stuff for this
would surely go too far.

I know!

city, host = ( locals().get('city', "default city"),
               locals().get('host', "default host") )

Testing if the variables only exists when actually assigned:

 >>> def foo(x, y):
 ...    if x: foo = None
 ...    if y: bar = "bar"
 ...    return locals()
 ... 
 >>> foo(False, False)
 {'y': False, 'x': False}
 >>> foo(False, True)
 {'y': True, 'x': False, 'bar': 'bar'}

Seems so.

What a monster, though. I don't even want to know if this, too, is
buggy in some way. It looks fragile.

Nikos, don't do this. The way to test if an assignment failed is to
use a try-catch. The way to know which one failed is to put each in
its own try-catch.



More information about the Python-list mailing list