[Python-Dev] PEP 463: Exception-catching expressions
Antoine Pitrou
solipsis at pitrou.net
Sat Feb 22 12:27:17 CET 2014
On Sat, 22 Feb 2014 22:13:58 +1100
Chris Angelico <rosuav at gmail.com> wrote:
> >
> > Well, can you propose the corresponding except-expression?
>
> It's hard to do hasattr itself without something messy - the best I
> can come up with is this:
>
> hasattr(x,"y") <-> (x.y or True except AttributeError: False)
But it's not the same. hasattr() returns a boolean, not an arbitrary
value.
> try:
> self._gdbframe.select()
> return True
> except AttributeError:
> print ('Unable to select frame: '
> 'this build of gdb does not expose a
> gdb.Frame.select method')
> return False
But then you can't distinguish between a missing "select" method
and an AttributeError raised by self._gdbframe.select() itself.
> but others are clearly expressions in disguise:
>
> Lib/aifc.py:882:
> if hasattr(f, 'mode'):
> mode = f.mode
> else:
> mode = 'rb'
> becomes
> mode = (f.mode except AttributeError: 'rb')
Not significantly less wordy. Note you can already write:
mode = getattr(f, 'mode', 'rb')
which is more concise.
> (In fact, I'm adding that one to the PEP's examples section.)
>
> Lib/cgi.py:145:
> if hasattr(fp,'encoding'):
> encoding = fp.encoding
> else:
> encoding = 'latin-1'
> becomes
> encoding = (fp.encoding except AttributeError: 'latin-1')
Same here:
encoding = getattr(fp, 'encoding', 'latin-1')
> Some could be done either way. If hasattr didn't exist, then this:
>
> Lib/argparse.py:597:
> if hasattr(params[name], '__name__'):
> params[name] = params[name].__name__
>
> could be written instead as:
> params[name] = (params[name].__name__
> except AttributeError: params[name])
This makes a useless assignment if the attribute doesn't exist; it also
spans a single expression over two lines instead of having two simple
statements. It's definitely worse IMO.
> Some are fairly clearly asking to be done as try/except, irrespective
> of this PEP:
>
> Lib/decimal.py:449:
> if hasattr(threading.current_thread(), '__decimal_context__'):
> del threading.current_thread().__decimal_context__
> becomes
> try: del threading.current_thread().__decimal_context__
> except AttributeError: pass
May hide a bug if threading.current_thread doesn't exist.
> Lib/inspect.py:1350:
> return sys._getframe(1) if hasattr(sys, "_getframe") else None
> becomes
> return (sys._getframe(1) except AttributeError: None)
May hide a bug if sys._getframe(1) itself raises AttributeError.
(etc.)
> I could continue this theme, but behold, as Rose Maybud said, I have
> said enough.
Yeah, none of these examples makes a convincing case that hasattr() is
useless, IMO.
Regards
Antoine.
More information about the Python-Dev
mailing list