Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!ecngs!feeder2.ecngs.de!newsfeed.freenet.ag!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'example:': 0.03; 'handler': 0.04; 'except:': 0.07; 'exit': 0.07; 'msg': 0.07; 'nicely': 0.07; 'permission.': 0.07; 'redirected': 0.07; 'skip:% 20': 0.07; 'try:': 0.07; 'check.': 0.09; 'dict': 0.09; 'failure.': 0.09; 'handling,': 0.09; 'http,': 0.09; "object's": 0.09; 'stderr': 0.09; 'thrown': 0.09; 'def': 0.10; 'thread': 0.11; 'dec': 0.15; '"bad': 0.16; '(and,': 0.16; "(it's": 0.16; '__del__': 0.16; "can't.": 0.16; 'commented': 0.16; 'forgiveness': 0.16; 'frameworks)': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'handlers.': 0.16; 'plus,': 0.16; 'request)': 0.16; 'structure.': 0.16; 'subject:compare': 0.16; 'usage,': 0.16; 'wrote:': 0.17; 'instance,': 0.17; 'string,': 0.17; 'thu,': 0.17; 'code,': 0.18; 'appropriate': 0.20; 'changes': 0.20; 'supposed': 0.21; 'exceptions': 0.22; 'explicit': 0.22; 'http': 0.22; 'keyerror:': 0.22; 'libraries': 0.22; "i'd": 0.22; 'errors': 0.23; "python's": 0.23; 'statement': 0.23; 'pass': 0.25; 'header:In-Reply-To:1': 0.25; 'looks': 0.26; 'wrote': 0.26; 'logging': 0.27; 'question': 0.27; 'message-id:@mail.gmail.com': 0.27; 'actual': 0.28; 'run': 0.28; 'post': 0.28; 'points': 0.29; "i'm": 0.29; 'maybe': 0.29; 'knows': 0.30; 'basic': 0.30; 'function': 0.30; 'error': 0.30; 'stuff': 0.30; 'code': 0.31; 'point': 0.31; 'gets': 0.32; 'problem.': 0.32; 'file': 0.32; 'info': 0.32; 'skip:s 30': 0.33; 'handle': 0.33; 'problem': 0.33; 'anyone': 0.33; 'to:addr:python-list': 0.33; 'another': 0.33; 'received:google.com': 0.34; 'generic': 0.35; 'returning': 0.35; 'pm,': 0.35; 'received:209.85.220': 0.35; "won't": 0.35; 'received:209.85': 0.35; 'something': 0.35; 'except': 0.36; 'but': 0.36; 'method': 0.36; 'possible': 0.37; 'option': 0.37; 'being': 0.37; 'usual': 0.37; 'received:209': 0.37; 'data': 0.37; 'subject:: ': 0.38; 'easier': 0.38; 'skip:l 20': 0.38; 'some': 0.38; 'instead': 0.39; 'to:addr:python.org': 0.39; 'easily': 0.39; 'called': 0.39; 'header:Received:5': 0.40; 'skip:a 30': 0.60; 'easy': 0.60; 'most': 0.61; 'chance': 0.61; "you'll": 0.62; 'time,': 0.62; 'is.': 0.62; 'between': 0.63; 'of:': 0.65; 'fact,': 0.69; 'receive': 0.71; 'race': 0.71; '"look': 0.84; 'plays': 0.84; 'production,': 0.91; 'hate': 0.93; 'technique': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=hpqirp8QV2jCKaf5LsmTGVNQfqtKbVaJJObZSG/oWhA=; b=AtukMRqQKk0cbfVich7gGJqEat3IW7hpfoPTVnRUZb5GOb5PwMwQi63Kek067EGccP hoZ+0cyJZhwL9wlKPrjB6d4ll4NrRzULxvBrmskYKXpuI3Je4UJmbIAjX+sGD7sW9wuO 5swL1j52yOMVw8pvXxCqHWpMUEjNMnobPwCxyxfCIy5vNjW5tJcWX4gu78VwMiSAyxma vmliSU1nUMYzSB1FXjuIVF7CHgNZ+CRCxxx7qtVKt5EuaUgJn5/Fjvb7q2+N/jxgTogx vTkKbYz5CpKUbgNjoX4IrPe1F54LNicrPvBsRzpmtoy8hlKumzwdo6kJLiWdkclAgnYS H78Q== MIME-Version: 1.0 In-Reply-To: <20121206084926.GD14400@hud> References: <50c01fe2$0$21853$c3e8da3$76491128@news.astraweb.com> <20121206084926.GD14400@hud> Date: Thu, 6 Dec 2012 20:34:28 +1100 Subject: Re: Confused compare function :) From: Chris Angelico To: python-list@python.org Content-Type: text/plain; charset=ISO-8859-1 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 71 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1354786472 news.xs4all.nl 6981 [2001:888:2000:d::a6]:60195 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:34370 On Thu, Dec 6, 2012 at 7:49 PM, Bruno Dupuis 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