On Thu, Dec 6, 2012 at 7:49 PM, Bruno Dupuis <python.ml.bruno.dup...@lisael.org> wrote: > > The point is Exceptions are made for error handling, not for normal > workflow. 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. >
This is the age-old question of EAFP vs LBYL. The check-first "Look Before You Leap" option has a small chance of race condition. If something changes between the 'if' and the usage, maybe from another thread or maybe a signal handler or perhaps some object's __del__ method gets called or who knows what, you'll have a problem. Python's usual philosophy is that it's Easier to Ask Forgiveness than Permission. Just do it, and jump out if you can't. This technique plays *very* nicely with generic handlers. For instance, at work I wrote an HTTP daemon that's supposed to receive XML-encoded POST data with a particular structure. The handler function (called once for every HTTP request) looks something like this, in Pythonesque pseudocode: def handler(req): try: msg = parse_xml(req.body) # returns a dict of dicts/lists/strings stuff = msg["soapenv:Envelope"]["soapenv:Body"]["GetItemTransactionsResponse"] sig = stuff["Item"]["ApplicationData"] if sig.does.not.match(): return "Bad request" sscanf(sig,"FOO %d %d %d",account,table,row) accountdata[account][table][row] = 1 return "Done and successful." except: log_error_to_stderr() return "Done." I don't particularly care _what_ the error is. Most of the time, I won't even bother to look at the log file (it's run via an Upstart job, and stderr is redirected to a file), but if I'm having problems, I can go check. Generally, exceptions thrown by that code are the result of malformed info packets; since it's basic HTTP, it's easy for anyone to send a request in, and I don't care to see those errors logged. In fact, the logging to stderr can even get commented out in production, and used only when there's actually a problem being diagnosed. To try to handle all possible errors in that code by LBLY, I would need to pepper the code with conditions and an appropriate 'return' statement (and, though the pseudo-code has the function returning a string, the actual code involves an explicit "send this response" call). Plus, I'd need to predict every possible failure. With EAFP, all I need is one simple "catch" handler for the whole block of code, and I can easily eyeball just a few function exit points to see that an appropriate HTTP response will always be sent. Each has its place. ChrisA -- http://mail.python.org/mailman/listinfo/python-list