There's a very Pythonic way to write that expression without explicitly writing a try-except block for a StopIteration
:
# some_iterable is some collection that can be iterated over
# e.g., a list, sequence, dict, set, itertools.combination(...)
for value in some_iterable:
print(value)
You can read up on the relevant PEPs 234 255 if you want to know more behind why StopIteration
was introduced and the logic behind iterators.
A general principle in python is to have one way to do something (see import this
), and preferably its beautiful, explicit, readable, and simple, which the pythonic method satisfies. Your equivalent code is only necessary as python doesn't give iterators a hasNext
member function; preferring people to just loop through the iterators directly (and if you need to do something else to just try reading it and catch an exception).
This automatic catching of an StopIteration
exception at the end of an iterator makes sense and is an analogue of the EOFError
raised if you read past an end of file.
In .NET, it is common practice to avoid the overuse of Exceptions. One argument is performance: in .NET, throwing an exception is computationally expensive.
Another reason to avoid their overuse is that it can be very difficult to read code that relies too much on them. Joel Spolsky's blog entry does a good job of describing the issue.
At the heart of the argument is the following quote:
The reasoning is that I consider exceptions to be no better than "goto's", considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto's:
1. They are invisible in the source code. Looking at a block of code, including functions which may or may not throw exceptions, there is no way to see which exceptions might be thrown and from where. This means that even careful code inspection doesn't reveal potential bugs.
2. They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function. Every time you call a function that can raise an exception and don't catch it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn't think about.
Personally, I throw exceptions when my code can't do what it is contracted to do. I tend to use try/catch when I'm about to deal with something outside of my process boundary, for instance a SOAP call, a database call, file IO, or a system call. Otherwise, I attempt to code defensively. It's not a hard and fast rule, but it is a general practice.
Scott Hanselman also writes about exceptions in .NET here. In this article he describes several rules of thumb regarding exceptions. My favourite?
You shouldn't throw exceptions for things that happen all the time. Then they'd be "ordinaries".
Best Answer
The answer to your question is you want meaningful exceptions.
In most contexts, this involves an exception that adds actionable information in one of two ways:
In your example, you aren't really adding anything to the normal exception. Catching and then effectively reraising the exception isn't useful. You could log this information, in which case you now added some value to the exception, but otherwise it's pointless.
Imagine this scenario:
It's entirely reasonable to imagine this scenario. You might make an http request. Most libraries have defined exception types, so you could catch those exceptions, and if it happens, do something.
The "something" is dependent on the specific application. In a http exception, maybe it's just retry the request. Etc.
But the point is catching the exception adds value and information and is actionable.