
On Sat, 22 Feb 2014 22:13:58 +1100 Chris Angelico <rosuav@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.