FYI. This is from comp.lang.python. Thought some people here might find it interesting, since similar issues arise in Ruby. Alex Martelli wrote: > > "Jerome Mrozak" <goose / enteract.com> wrote in message > news:3A35D546.A4731B5B / enteract.com... > > I realize that Python allows me to catch exceptions. But being a novice > > I'm not sure if they are used much in the 'real world'. > > Oh yes they are -- an absolutely crucial and fundamental technique. > > > In Java, my current bread-winning language, exceptions are caught mostly > > because the compiler/language demands it. I haven't yet designed a > > To be specific: in Java, if a certain method's body can raise > certain exceptions it does not catch, you have to _declare_ this > as a part of the method's signature. A very good design choice > within a language hinging on compile-time static typechecking, > and vastly superior to C++'s semantics for exception declarations > (which were hampered by the need for backwards compatibility). > > > Another way of putting it is, if the try-catch-else didn't exist would > > anyone be terribly put out? (If not then the construct isn't much > > used...) > > Python programming would be utterly different (and much less fun) > if one could not use try/except. (try/finally could more easily > be replaced by a slightly different semantics on guaranteed > finalization of objects, and it's a pity a 'try' can't have one > or more 'except' clauses _followed_ by a 'finally' one, etc, etc, > but these are secondary issues). > > Specifically: in Python, exceptions are NOT for 'exceptional' > conditions ONLY (as good programming style demands they be in > C++, and, ideally, in Java just as well). exceptions are the > NORMAL Python way to report on "I can't do this, Jim". > > You want to exit from a deeply-nested loop, or recursion? Use > exceptions. You want to terminate a tree-walk over directories? > Use exceptions. > > Perhaps the single most important issue is the design pattern > named (after a famous quote from Commodore Hopper, Cobol's > inventor) "It's easier to ask forgiveness than permission". > > A typical setting for it: somebody asks, "How do I check that > a file exists?". What they most often MEAN by this: 'how do > I check that a file exists AND is authorized to be read by > the user currently running the program AND THEN actually go > and open the file for reading?" -- and the best answer to this > question is NOT, e.g.: > > def open_if_ok1(filepath): > if os.access(filepath, os.R_OK): > return open(filepath, 'r') > else: > return None > > Why not? Well, for example, the world is multi-tasked: there > is a small but non-null window of time between the instant > in which os.access gives you the go-ahead, and the following > instant in which you actually go and 'use' that permission! > The file *might* go away or get locked against reading in > that small window -- the kind of problem, connected with 'race > conditions', that's EXCEEDINGLY hard to pinpoint, reproduce, > and debug, when it comes up... > > There is a simpler, safer, sounder way...: > > def open_if_ok2(filepath): > try: return open(filepath, 'r') > except IOError: return None > > "Just do it" -- making sure expected possible errors are > caught and handled in according with the semantic specs > (here, we assume, None is to be returned if the filepath > can't be opened for reading, for whatever reason). > > Or, take another example. "Am I allowed to set attribute > foo of object bar to the Unicode string u'fee fie foo fum'"? > > How do you check for *that*, when the object can have any > type, and, if it's an instance-object, its __setattr__ might > do whatever kinds of semantic checks on the attribute being > set and/or the value it's being set to...? > > 'Asking for permission' is basically unfeasible here. Much > better to 'ask for forgiveness' if needed, e.g.: > > def setattr_ok(obj, attr, value): > try: setattr(obj, attr, value) > except (AttributeError, ValueError): return 0 > else: return 1 > > (Some might prefer a wider 'except: return 0' clause, but > most often it's better to be specific in catching exceptions). > > Alex Conrad Schneiker (This note is unofficial and subject to improvement without notice.)