On Sat, 2011-10-08 at 22:23 +1100, Steven D'Aprano wrote:
Ron Adam wrote:
That leads to possibly quite a few more try-except blocks, and possibly more nested try-except blocks. At some point, it may start to seem like it's a better idea to avoid them rather than use them.
Or refactor parts of your code into a function.
Of course refactoring a bit of code so as to be sensitive to the context would help, but it's not always as straight forward as it seems.
It's not a tool you would use everywhere.
What if you can catch an exception specifically from a particular function or method, but let other unexpected "like" exceptions bubble through...
try: ... i = s.index('bar') ... except ValueError from s.index as exc: <handle s.index ValueError>
I can't imagine that this would even be *possible*, but even if it is, I would say it certainly isn't *desirable*.
(1) You're repeating code you expect to fail: you write s.index twice, even though it only gets called once.
Right, and if all you are interested in is just that, you would just wrap that part in regular try except and not do it this way.
(2) The semantics are messy and unclear. Suppose you have this:
try: ... i = s.index(a) j = s.index(b) + s.index(c) t = s k = t.index(d) method = s.index l = method(e) ... except ValueError from s.index: ...
Which potential s.index exceptions will get caught? All of them? Some of them? Only i and j? What if you want to catch only some but not others?
Any of them you put inside the try-except block. But it would not catch a ValueError caused by some other function or method in the '...' part of the example.
How will this construct apply if s or s.index is rebound, or deleted, inside the try block?
s += "spam" m = s.index(f)
The rebinding of the name doesn't matter as it is an object comparison.
It may work more like...
try: ... s += "spam" m = s.index(f) ... except ValueError as e: if e.__cause__ is str.index: ... raise
What about this?
alist = ['spam', 'ham', s, 'eggs'] results = [x.index('cheese') for x in alist]
Should your proposal catch an exception in the list comp?
Sure, why not?
What if you call a function which happens to call s.index? Will that be caught?
x = some_function(spam, ham, s, eggs) # happens to call s.index
The str.index method would be the source of the exception unless some_function() catches it. It could raise a new exception and then it would be reported as the cause.