On 12/06/2012 08:47 AM, Steven D'Aprano wrote:
On Thu, 06 Dec 2012 09:49:26 +0100, Bruno Dupuis wrote:
The point is Exceptions are made for error handling, not for normal
workflow.
That's certainly not the case in Python. Using exceptions for flow
control is a standard part of the language.
IndexError and StopIteration are used to detect the end of lists or
iterators in for loops.
GeneratorExit is used to request that generators exit.
SysExit is used to exit the interpreter.
There is nothing wrong with using exceptions for flow control in
moderation.
I hate when i read that for example:
try:
do_stuff(mydict[k])
except KeyError:
pass
(loads of them in many libraries and frameworks) instead of:
if k in mydict:
do_stuff(mydict[k])
Note that the performances are better with the latter.
Not so. Which one is faster will depend on how often you expect to fail.
If the keys are nearly always present, then:
try:
do_stuff(mydict[k])
except KeyError:
pass
will be faster. Setting up a try block is very fast, about as fast as
"pass", and faster than "if k in mydict".
But if the key is often missing, then catching the exception will be
slow, and the "if k in mydict" version may be faster. It depends on how
often the key is missing.
[...]
It depends also on the context, I'd be more 'permissive' a short script
than into a large program, framework, or lib, for the very reason it's
easy to know all code interactions.
In my coder life, i spent more time debugging silently swallowed
exceptions than logging abnormal behaviours.
That's fine. I agree with you about not silently swallowing errors. Where
I disagree is that you said "never ever", which is an exaggeration.
Remember that exceptions are not always errors.
Problem: take a list of strings, and add up the ones which are integers,
ignoring everything else.
Solution:
total = 0
for s in list_of_strings:
try:
total += int(s)
except ValueError:
pass # Not a number, ignore it.
Why would you want to log that? It's not an error, it is working as
designed. I hate software that logs every little thing that happens, so
that you cannot tell what's important and what isn't.
Is perfectly right to use try catch for a flow control.
Just think in something more complex like this.
try:
self._conn = MySQLdb.connect(host=host,
user=user,
passwd=passwd,
db=db)
except:
logging.info("Error de conexion con la base de datos")
inform(subject = 'Db down on app %s' % app, body=sbody)
Or maybe something like this.
try:
cursor.execute(sqli, data)
self._conn.commit()
except:
try:
self._conn.rollback()
cursor.execute(sqli, data)
self._conn.commit()
except Exception, e:
pass
# print e
# logging.info('ERROR en la insercion %s' % e)
This is pretty dumb, but is a valid example, on what you can do with try
catch
--
http://mail.python.org/mailman/listinfo/python-list