Hi Steven, Yea this is great. Thanks for the feedback.
On Saturday, August 24, 2013 3:27:45 AM UTC-7, Steven D'Aprano wrote: > On Fri, 23 Aug 2013 22:25:55 -0700, snarf wrote: > > > > [...] > > > * Seems like exception handing within Classes is largely avoided and is > > > typically only used when calling external libraries. > > > > There is certainly no rule "avoid exceptions inside classes". Methods > > often raise exceptions to signal an error, e.g.: > > > > "My string".index("spam") > > > > > > Less common, methods can raise exceptions as part of their flow control. > > The most obvious example is StopIteration, used by iterators and often by > > __iter__ or next methods. > > > > > > > * Try/Except type > > > statements seem to be used more within modules, main functions, wrapper > > > scripts. > > > > It depends on whose code you are reading. I don't write a lot of classes, > > but when I do, I often use try...except inside them. > > > > If try...except gets used more frequently in module's top level, it is > > because the sort of things that you do at the top level often needs > > exception handling. For example, you might have a fallback module: > > > > try: > > import this_module > > except ImportError: > > import that_module as this_module > > > > > > You will very rarely see that inside a class, since you very rarely > > import modules inside a class. > > > > > > > * Classes should be coded in a way that exceptions > > > > I think you forgot to finish the sentence. > > > > > > > * Better to > > > never write your own exceptions (unless you absolutely have to). > > > > That depends. > > > > On the one hand, nobody wants a million different exception types. On the > > other hand, nobody wants just *one* exception type, and no way to > > distinguish between different kinds of errors. Somewhere between one and > > one million is an appropriate number of exception types. > > > > The right answer is to be conservative about creating new exceptions, but > > don't be scared to create one when you need one. > > > > But when you do, it is often better to subclass from an appropriate built- > > in exception like ValueError or TypeError or similar, than to subclass > > from Exception itself. > > > > > > > * Using > > > Exception is typically a bad. More specific the better. > > > > Yes, you should always try to catch the specific exceptions you care > > about: > > > > > > # Best > > except ValueError, OverflowError, ZeroDivisionError: > > > > > > # Not so good > > except Exception: > > > > > > # Worst > > except: > > > > > > Don't use the last one, except maybe in the interactive interpreter, > > since it will catch *everything*, even exceptions that probably shouldn't > > be caught like KeyboardInterrupt. > > > > > > > * Exceptions > > > should never fail silently. (Should exceptions always be logged?) > > > > Certainly not. Exceptions should fail silently if you don't care about > > them. For example, when connecting to a website, there are many temporary > > errors that can occur. The best way to handle them is to catch the > > exception, sleep for a little while, then try again. You need only care > > if repeated attempts to connect, with larger and larger sleeps, continue > > to fail. > > > > Of course, you might have a debug mode that logs all of these, but if > > your web browser logged every single time a webpage was slow to respond, > > you would soon run out of disk space :-) > > > > *Errors* should never fail silently, unless explicitly silenced. But an > > error isn't an error if you don't care about it, and an exception is not > > necessarily an error. > > > > This is an error, because converting a number to uppercase cannot > > possibly mean anything: > > > > mystring = 42 > > mystring.upper() > > > > > > This is not necessarily an error, since "the list is empty" could be a > > legitimate situation: > > > > mylist = [] > > first = mylist[0] > > > > In this case, it may be appropriate to catch the exception, and either > > silently swallow it, or do something else. > > > > > > > Best site I have found for exceptions (hopefully this helps someone): * > > > http://c2.com/cgi/wiki?ExceptionPatterns > > > > I haven't read that page for a long time, but as I recall the c2.com > > website, a lot of the ideas there are better suited to Java and C/C++ > > (and occasionally Lisp) rather than Python. But still, a valuable (if > > often confusing) resource. > > > > > > > > > I'd be interested in hearing others thoughts on this topic with regards > > > to best practices for when to use exceptions, and when to avoid using > > > exceptions. > > > > The try part of a try...except is *very* fast to set up. It's about as > > fast as a "pass" (do nothing), so it has little overhead. > > > > On the other hand, actually *catching* an exception is quite heavy. So > > code that catches lots and lots of exceptions may be slow. In that case, > > it may be faster to "look before you leap" and test ahead of time: > > > > # this is faster if most lists are not empty > > try: > > process(mylist[0]) > > except IndexError: > > handle_empty_list() > > > > # this is faster if many lists are empty > > if mylist: > > process(mylist[0]) > > else: > > handle_empty_list() > > > > > > Only profiling your data can tell you which you should use. > > > > > > On the other hand, here you should *always* use try...except: > > > > try: > > myfile = open("name") > > except IOError: > > handle_error() > > > > > > Because this code is wrong: > > > > if os.path.exists("name"): > > myfile = open("name") > > else: > > handle_error() > > > > > > It's wrong for a couple of reasons: > > > > - just because the file exists, doesn't mean you can open it; > > > > - even if the file exists when you call the os.path.exists function, > > doesn't mean it will still exist a millisecond later when you try to open > > it. > > > > > > > > Hope this is helpful, > > > > > > > > > > -- > > Steven -- http://mail.python.org/mailman/listinfo/python-list