I have it drilled into my head that (at least in PHP) it is badbadmojo to use try... catch
blocks for flow control. What I\'ve learned is to use them only to h
I've done a bit more reading, and have realized one other important thing no one has mentioned yet: in Python, there is no distinction between Errors and Exceptions. I knew this, but I don't think I had grasped the significance until now.
In PHP, you can wrap $page->GetContent();
in try...catch
blocks all you want, but if $page
is not an object, your application will still come to a screeching halt with the resulting fatal error. So in PHP (and any other language where errors cannot be caught), you need a certain level of LBYL.
Python basically says, "that's stupid, I should be able to catch those." Just try to do what you need to do, and deal with any fallout in the except
block.
Here is a great article on exception handling I came across.
I don't believe that the EAFP encourages the use of exceptions for flow control. Rather, it tells us that we needn't bother checking for the existence of a particular key in a dictionary or property of an object before we reference it.
Throwing exceptions as an alternative to if
statements or having correct while
statements or instead of using break
or continue
inside of a loop does not fall under that category. That's lazy, error-prone progamming and it should be avoided.
Historically, in languages like C++, exceptions have been very slow compared to other forms of flow control in the same language.
In C++, there are two things at work:
This disparity in performance led to the general wisdom behind exceptions: only do it for unusual things, so it's only used where it's most beneficial and not where it'll hurt performance.
This does not apply to high-level languages. This is also for two reasons:
Exceptions still aren't free, but the disparity is no longer something to worry so much about. This means the general wisdom formed in C++ is misapplied here. Exceptions are regularly used in normal program flow.
In fact, they're built into language, in constructs you use all the time. Every time you use an iterator--every for x in xrange(1000)
, a StopIteration
exception is used to end the loop.
Choose exceptions or linear flow control in Python based on which makes more sense. Don't choose based on performance, unless you're actually in an inner loop where performance matters; in that case, as always, profile and find out if it actually matters.
(I can't speak for PHP.)
the great Alex Martelli gives a good overview of EAFP vs. LBYL in the book 'Python In A Nutshell'. (He heavily leans towards using EAFP)
def worth reading:
http://books.google.com/books?id=JnR9hQA3SncC&lpg=PA134&ots=JaaWGy-24u&dq=alex%20martelli%20eafp%20lbyl&pg=PA134#v=onepage&q&f=false
To answer the question: Yes. Python exceptions are cheap. An if test is cheaper still, so yes, you should just use exceptions for "unexpected" situations, in as much as if you expect the code to fail most times, check before you do it. Since the if-check will avoid also the actual trying as well as the raising and catching of the exception, that will be much faster in a situation that fails. (Unless, of course, the test in itself is expensive).
But there is no point in avoiding exceptions as such. Python will not drag to a crawl because you catch a lot of exceptions.
And as usual: Optimization without profiling is premature.
There's a specific exception that is only supposed to be used in normal execution flow: StopIteration
. This implies to me that Python's creator doesn't think exception overhead is out of line.
Whether this is because exception handling is uber-efficient or the rest of the language is just slow by comparison is another question...