Confused compare function :)
Chris Angelico
rosuav at gmail.com
Thu Dec 6 04:34:28 EST 2012
On Thu, Dec 6, 2012 at 7:49 PM, Bruno Dupuis
<python.ml.bruno.dupuis at 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
More information about the Python-list
mailing list