[Python-Dev] PEP 463: Exception-catching expressions

Rob Cliffe rob.cliffe at btinternet.com
Mon Feb 24 19:30:52 CET 2014


Some of your points have been answered by others, I'll try to avoid 
repetition.

On 21/02/2014 19:04, Yury Selivanov wrote:
> [snip]
>
> Inconvenience of dict[] raising KeyError was solved by
> introducing the dict.get() method. And I think that
>
> dct.get('a', 'b')
>
> is 1000 times better than
>
> dct['a'] except KeyError: 'b'
Do you?  I don't.  "Explicit is better than implicit".  I think this may 
be partly a matter of familiarity.
>
>> Translate numbers to names, falling back on the numbers::
>>              g = grp.getgrnam(tarinfo.gname)[2] except KeyError: 
>> tarinfo.gid
>>              u = pwd.getpwnam(tarinfo.uname)[2] except KeyError: 
>> tarinfo.uid
>>
>>              # Lib/tarfile.py:2198:
>>              try:
>>                  g = grp.getgrnam(tarinfo.gname)[2]
>>              except KeyError:
>>                  g = tarinfo.gid
>>              try:
>>                  u = pwd.getpwnam(tarinfo.uname)[2]
>>              except KeyError:
>>                  u = tarinfo.uid
> This one is a valid example, but totally unparseable by
> humans.
Again, I find the more concise version easier to read than the 
original.  It is dense, yes.  It takes time to read and absorb, sure -  
but so does the original 8-line version.
And it makes the repetition of the same code structure much more obvious.
>>
>
> I think all of the above more readable with try statement.
>>
>> Retrieving a message from either a cache or the internet, with auth
>> check::
>>
>>      logging.info("Message shown to user: %s",((cache[k]
>>          except LookupError:
>>              (backend.read(k) except OSError: 'Resource not available')
>>          )
>>          if check_permission(k) else 'Access denied'
>>      ) except BaseException: "This is like a bare except clause")
>>
>>      try:
>>          if check_permission(k):
>>              try:
>>                  _ = cache[k]
>>              except LookupError:
>>                  try:
>>                      _ = backend.read(k)
>>                  except OSError:
>>                      _ = 'Resource not available'
>>          else:
>>              _ = 'Access denied'
>>      except BaseException:
>>          _ = "This is like a bare except clause"
>>      logging.info("Message shown to user: %s", _)
>
I think there is a consensus that this was a poor example, unless 
intended to show how the new construction (like any other) could be 
abused to produce hard-to-understand code.

> If you replace '_' with a 'msg' (why did you use '_'??)
> then try statements are *much* more readable.
>
>> [snip]
>>
>> Lib/ipaddress.py:343::
>>              try:
>>                  ips.append(ip.ip)
>>              except AttributeError:
>>                  ips.append(ip.network_address)
>> Becomes::
>>              ips.append(ip.ip except AttributeError: ip.network_address)
> or it may become:
>
> ips.append(getattr(ip, 'ip', ip.network_address))
>
> or
>
> address = getattr(ip, 'ip', ip.network_address)
> ips.append(address)
Please note that any of these is an improvement on the original, in that 
they don't trap an AttributeError evaluating ips.append.  (The old try 
... except syntax can be used incorrectly, just as any new syntax can.)
>
> ---
>
> All in all, your proposal scares me. I doesn't make python
> code readable,
Again, a personal judgement.
> it doesn't solve the problem of overbroad
> exceptions handling (you have couple examples of overbroad
> handling in your PEP examples section).
>
> Yes, some examples look neat. But your syntax is much easier
> to abuse, than 'if..else' expression,
Why?  Any syntax can be abused.  I can easily abuse if..else if I want to:
ErrorMessage = (None if eggs else "No eggs") if ham else "No ham" if 
eggs else "No ham or eggs" # Tested

Suppose you were learning Python.
Which is easier, to learn lots of special methods (dict.get, getattr 
etc.), or to learn ONE self-explanatory form of syntax that covers them all:
     Dict[Key] except KeyError: default
     List[Index] except IndexError: default
     x.y except AttributeError: default
(Of course, I'm not saying "Don't use getattr".  Just that you could get 
by if you've never heard of it.)



More information about the Python-Dev mailing list