Exception as the primary error handling mechanism?

Discussion in 'Python' started by Peng Yu, Jan 1, 2010.

  1. Peng Yu

    Peng Yu Guest

    I observe that python library primarily use exception for error
    handling rather than use error code.

    In the article API Design Matters by Michi Henning

    Communications of the ACM
    Vol. 52 No. 5, Pages 46-56
    10.1145/1506409.1506424
    http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext

    It says "Another popular design flaw—namely, throwing exceptions for
    expected outcomes—also causes inefficiencies because catching and
    handling exceptions is almost always slower than testing a return
    value."

    My observation is contradicted to the above statement by Henning. If
    my observation is wrong, please just ignore my question below.

    Otherwise, could some python expert explain to me why exception is
    widely used for error handling in python? Is it because the efficiency
    is not the primary goal of python?
     
    Peng Yu, Jan 1, 2010
    #1
    1. Advertising

  2. Peng Yu

    Chris Rebert Guest

    On Thu, Dec 31, 2009 at 8:47 PM, Peng Yu <> wrote:
    > I observe that python library primarily use exception for error
    > handling rather than use error code.
    >
    > In the article API Design Matters by Michi Henning
    >
    > Communications of the ACM
    > Vol. 52 No. 5, Pages 46-56
    > 10.1145/1506409.1506424
    > http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >
    > It says "Another popular design flaw—namely, throwing exceptions for
    > expected outcomes—also causes inefficiencies because catching and
    > handling exceptions is almost always slower than testing a return
    > value."
    >
    > My observation is contradicted to the above statement by Henning. If
    > my observation is wrong, please just ignore my question below.
    >
    > Otherwise, could some python expert explain to me why exception is
    > widely used for error handling in python? Is it because the efficiency
    > is not the primary goal of python?


    Correct; programmer efficiency is a more important goal for Python instead.
    Python is ~60-100x slower than C;[1] if someone is worried by the
    inefficiency caused by exceptions, then they're using completely the
    wrong language.

    Cheers,
    Chris
    --
    http://blog.rebertia.com

    [1] http://shootout.alioth.debian.org/u...s-are-fastest.php?gcc=on&python=on&calc=chart
     
    Chris Rebert, Jan 1, 2010
    #2
    1. Advertising

  3. On Thu, Dec 31, 2009 at 11:47 PM, Peng Yu <> wrote:
    > I observe that python library primarily use exception for error
    > handling rather than use error code.
    >
    > In the article API Design Matters by Michi Henning
    >
    > Communications of the ACM
    > Vol. 52 No. 5, Pages 46-56
    > 10.1145/1506409.1506424
    > http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >
    > It says "Another popular design flaw—namely, throwing exceptions for
    > expected outcomes—also causes inefficiencies because catching and
    > handling exceptions is almost always slower than testing a return
    > value."
    >
    > My observation is contradicted to the above statement by Henning. If
    > my observation is wrong, please just ignore my question below.
    >
    > Otherwise, could some python expert explain to me why exception is
    > widely used for error handling in python? Is it because the efficiency
    > is not the primary goal of python?
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >


    Read the quote again "Another popular design flaw—namely, throwing
    exceptions *for expected outcomes*"
    In Python, throwing exceptions for expected outcomes is considered
    very bad form (well, except for StopIteration but that should almost
    never be handled directly by the programmer).

    To answer why people recommend using "Easier to Ask Forgiveness than
    Permission" as opposed to "Look Before You Leap" : Because of the way
    it's implemented, Python works quite differently from most languages.
    An attribute look-up is rather expensive because it's a hash table
    look-up at run time. Wrapping a small piece of code in a try block
    however, isn't (relatively) very expensive at all in Python. It's only
    catching the exception that's expensive, but if you're catching the
    exception, something has gone wrong anyway and performance isn't your
    biggest issue.
     
    Benjamin Kaplan, Jan 1, 2010
    #3
  4. On Thu, 31 Dec 2009 20:47:49 -0800, Peng Yu wrote:

    > I observe that python library primarily use exception for error handling
    > rather than use error code.
    >
    > In the article API Design Matters by Michi Henning
    >
    > Communications of the ACM
    > Vol. 52 No. 5, Pages 46-56
    > 10.1145/1506409.1506424
    > http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >
    > It says "Another popular design flaw—namely, throwing exceptions for
    > expected outcomes—also causes inefficiencies because catching and
    > handling exceptions is almost always slower than testing a return
    > value."


    This is very, very wrong.

    Firstly, notice that the author doesn't compare the same thing. He
    compares "catching AND HANDLING" the exception (emphasis added) with
    *only* testing a return value. Of course it is faster to test a value and
    do nothing, than it is to catch an exception and then handle the
    exception. That's an unfair comparison, and that alone shows that the
    author is biased against exceptions.

    But it's also wrong. If you call a function one million times, and catch
    an exception ONCE (because exceptions are rare) that is likely to be
    much, much faster than testing a return code one million times.

    Before you can talk about which strategy is faster, you need to
    understand your problem. When exceptions are rare (in CPython, about one
    in ten or rarer) then try...except is faster than testing each time. The
    exact cut-off depends on how expensive the test is, and how much work
    gets done before the exception is raised. Using exceptions is only slow
    if they are common.

    But the most important reason for preferring exceptions is that the
    alternatives are error-prone! Testing error codes is the anti-pattern,
    not catching exceptions.

    See, for example:

    http://c2.com/cgi/wiki?UseExceptionsInsteadOfErrorValues
    http://c2.com/cgi/wiki?ExceptionsAreOurFriends
    http://c2.com/cgi/wiki?AvoidExceptionsWheneverPossible

    Despite the title of that last page, it has many excellent arguments for
    why exceptions are better than the alternatives.

    (Be warned: the c2 wiki is filled with Java and C++ programmers who
    mistake the work-arounds for quirks of their language as general design
    principles. For example, because exceptions in Java are evcen more
    expensive and slow than in Python, you will find lots of Java coders
    saying "don't use exceptions" instead of "don't use exceptions IN JAVA".)

    There are many problems with using error codes:

    * They complicate your code. Instead of returning the result you care
    about, you have to return a status code and the return result you care
    about. Even worse is to have a single global variable to hold the status
    of the last function call!

    * Nobody can agree whether the status code means the function call
    failed, or the function call succeeded.

    * If the function call failed, what do you return as the result code?

    * You can't be sure that the caller will remember to check the status
    code. In fact, you can be sure that the caller WILL forget sometimes!
    (This is human nature.) This leads to the frequent problem that by the
    time a caller checks the status code, the original error has been lost
    and the program is working with garbage.

    * Even if you remember to check the status code, it complicates the code,
    makes it less readable, confuses the intent of the code, and often leads
    to the Arrow Anti-pattern: http://c2.com/cgi/wiki?ArrowAntiPattern

    That last argument is critical. Exceptions exist to make writing correct
    code easier to write, understand and maintain.

    Python uses special result codes in at least two places:

    str.find(s) returns -1 if s is not in the string
    re.match() returns None is the regular expression fails

    Both of these are error-prone. Consider a naive way of getting the
    fractional part of a float string:

    >>> s = "234.567"
    >>> print s[s.find('.')+1:]

    567

    But see:

    >>> s = "234"
    >>> print s[s.find('.')+1:]

    234

    You need something like:

    p = s.find('.')
    if p == -1:
    print ''
    else:
    print s[p+1:]



    Similarly, we cannot safely do this in Python:


    >>> re.match(r'\d+', '123abcd').group()

    '123'
    >>> re.match(r'\d+', 'abcd').group()

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'

    You need to do this:

    mo = re.match(r'\d+', '123abcd')
    if mo is not None: # or just `if mo` will work
    mo.group()


    Exceptions are about making it easier to have correct code. They're also
    about making it easier to have readable code. Which is easier to read,
    easier to understand and easier to debug?

    x = function(1, 2, 3)
    if x != -1:
    y = function(x, 1, 2)
    if y != -1:
    z = function(y, x, 1)
    if z != -1:
    print "result is", z
    else:
    print "an error occurred"
    else:
    print "an error occurred"
    else:
    print "an error occurred"


    versus:


    try:
    x = function(1, 2, 3)
    y = function(x, 1, 2)
    print "result is", function(y, x, 1)
    except ValueError:
    print "an error occurred"



    In Python, setting up the try...except block is very fast, about as fast
    as a plain "pass" statement, but actually catching the exception is quite
    slow. So let's compare string.find (which returns an error result) and
    string.index (which raises an exception):


    >>> from timeit import Timer
    >>> setup = "source = 'abcd'*100 + 'e'"
    >>> min(Timer("p = source.index('e')", setup).repeat())

    1.1308379173278809
    >>> min(Timer("p = source.find('e')", setup).repeat())

    1.2237567901611328

    There's hardly any difference at all, and in fact index is slightly
    faster. But what about if there's an exceptional case?


    >>> min(Timer("""

    .... try:
    .... p = source.index('z')
    .... except ValueError:
    .... pass
    .... """, setup).repeat())
    3.5699808597564697
    >>> min(Timer("""

    .... p = source.find('z')
    .... if p == -1:
    .... pass
    .... """, setup).repeat())
    1.7874350070953369


    So in Python, catching the exception is slower, in this case about twice
    as slow. But remember that the "if p == -1" test is not free. It might be
    cheap, but it does take time. If you call find() enough times, and every
    single time you then test the result returned, that extra cost may be
    more expensive than catching a rare exception.

    The general rule in Python is:

    * if the exceptional event is rare (say, on average, less than about one
    time in ten) then use a try...except and catch the exception;

    * but if it is very common (more than one time in ten) then it is faster
    to do a test.


    > My observation is contradicted to the above statement by Henning. If my
    > observation is wrong, please just ignore my question below.
    >
    > Otherwise, could some python expert explain to me why exception is
    > widely used for error handling in python? Is it because the efficiency
    > is not the primary goal of python?


    Yes.

    Python's aim is to be fast *enough*, without necessarily being as fast as
    possible.

    Python aims to be readable, and to be easy to write correct, bug-free
    code.


    --
    Steven
     
    Steven D'Aprano, Jan 1, 2010
    #4
  5. Peng Yu

    Aahz Guest

    In article <>,
    Benjamin Kaplan <> wrote:
    >
    >In Python, throwing exceptions for expected outcomes is considered
    >very bad form [...]


    Who says that? I certainly don't.
    --
    Aahz () <*> http://www.pythoncraft.com/

    Weinberg's Second Law: If builders built buildings the way programmers wrote
    programs, then the first woodpecker that came along would destroy civilization.
     
    Aahz, Jan 1, 2010
    #5
  6. Peng Yu wrote:
    > I observe that python library primarily use exception for error
    > handling rather than use error code.

    [...]
    > It says "Another popular design flaw—namely, throwing exceptions for
    > expected outcomes—also causes inefficiencies because catching and
    > handling exceptions is almost always slower than testing a return
    > value."
    >
    > My observation is contradicted to the above statement by Henning. If
    > my observation is wrong, please just ignore my question below.


    Your observation is not wrong, but, as Benjamin already explained,
    you are misinterpreting Michi Henning's statement. He doesn't condemn
    exception handling per se, but only for the handling of *expected*
    outcomes. He would consider using exceptions fine for *exceptional*
    output, and that is exactly the way they are used in the Python API.

    Notice that in cases where the failure may be expected, Python
    also offers variants that avoid the exception:
    - if you look into a dictionary, expecting that a key may not
    be there, a regular access, d[k], may give a KeyError. However,
    alternatively, you can use d.get(k, default) which raises no
    exception, and you can test "k in d" in advance.
    - if you open a file, not knowing whether it will be there,
    you get an IOError. However, you can use os.path.exists in
    advance to determine whether the file is present (and create
    it if it's not).

    So, in these cases, it is a choice of the user to determine whether
    the error case is exceptional or not.

    Regards,
    Martin
     
    Martin v. Loewis, Jan 1, 2010
    #6
  7. On Jan 1, 12:43 am, (Aahz) wrote:
    > In article <>,
    > Benjamin Kaplan  <> wrote:
    > >In Python, throwing exceptions for expected outcomes is considered
    > >very bad form [...]

    >
    > Who says that?  I certainly don't.


    Agreed.

    int("asdf") is supposed to return what, exactly? Any language that
    tries to return an int is horribly broken.
     
    Jonathan Gardner, Jan 1, 2010
    #7
  8. On Fri, 01 Jan 2010 11:34:19 +0100 "Martin v. Loewis"
    <> wrote:

    > Your observation is not wrong, but, as Benjamin already explained,
    > you are misinterpreting Michi Henning's statement. He doesn't condemn
    > exception handling per se, but only for the handling of *expected*
    > outcomes. He would consider using exceptions fine for *exceptional*
    > output, and that is exactly the way they are used in the Python API.


    May I point out at this point that "exceptional" does not mean
    "unexpected"? You catch exceptions, not unexpectations. An exception
    is rare, but not surprising. Case in point: StopIteration.

    To put it differently: When you write "catch DeadParrot", you certainly
    expect to get a DeadParrot once in a while -- why else would you get it
    in your head to try and catch it? An unexpected exception is the one
    that crashes your program.

    /W

    --
    INVALID? DE!
     
    Andreas Waldenburger, Jan 1, 2010
    #8
  9. On Fri, 01 Jan 2010 02:43:21 -0800, Jonathan Gardner wrote:

    > On Jan 1, 12:43 am, (Aahz) wrote:
    >> In article <>,
    >> Benjamin Kaplan  <> wrote:
    >> >In Python, throwing exceptions for expected outcomes is considered
    >> >very bad form [...]

    >>
    >> Who says that?  I certainly don't.

    >
    > Agreed.
    >
    > int("asdf") is supposed to return what, exactly? Any language that tries
    > to return an int is horribly broken.



    [sarcasm]
    No no, the right way to deal with that is have int("asdf") return some
    arbitrary bit pattern, and expect the user to check a global variable to
    see whether the function returned a valid result or not. That's much
    better than catching an exception!
    [/sarcasm]


    --
    Steven
     
    Steven D'Aprano, Jan 1, 2010
    #9
  10. On Fri, 01 Jan 2010 00:26:09 -0500, Benjamin Kaplan wrote:

    > On Thu, Dec 31, 2009 at 11:47 PM, Peng Yu <> wrote:
    >> I observe that python library primarily use exception for error
    >> handling rather than use error code.
    >>
    >> In the article API Design Matters by Michi Henning
    >>
    >> Communications of the ACM
    >> Vol. 52 No. 5, Pages 46-56
    >> 10.1145/1506409.1506424
    >> http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >>
    >> It says "Another popular design flaw—namely, throwing exceptions for
    >> expected outcomes—also causes inefficiencies because catching and
    >> handling exceptions is almost always slower than testing a return
    >> value."
    >>
    >> My observation is contradicted to the above statement by Henning. If my
    >> observation is wrong, please just ignore my question below.
    >>
    >> Otherwise, could some python expert explain to me why exception is
    >> widely used for error handling in python? Is it because the efficiency
    >> is not the primary goal of python?
    >> --
    >> http://mail.python.org/mailman/listinfo/python-list
    >>
    >>

    > Read the quote again "Another popular design flaw—namely, throwing
    > exceptions *for expected outcomes*"
    > In Python, throwing exceptions for expected outcomes is considered very
    > bad form (well, except for StopIteration but that should almost never be
    > handled directly by the programmer).



    Exceptions are *exceptional*, not "errors" or "unexpected". They are
    exceptional because they aren't the "normal" case, but that doesn't mean
    they are surprising or unexpected. Are you surprised that your "for x in
    range(1000)" loop comes to an end? Of course you are not -- it is
    completely expected, even though less than 1% of the iterations are the
    last loop. The end of the sequence is EXCEPTIONAL but not UNEXPECTED.

    If you program without expecting that keys can sometimes be missing from
    dictionaries (KeyError), or that you might sometimes have to deal with a
    list index that is out of range (IndexError), or that the denominator in
    a division might be zero (ZeroDivisionError), then you must be writing
    really buggy code. None of these things are unexpected, but they are all
    exceptional.

    The urllib2 module defines a HTTPError class, which does double-duty as
    both an exception and a valid HTTP response. If you're doing any HTTP
    programming, you better expect to deal with HTTP 301, 302 etc. codes, or
    at least trust that the library you use will transparently handle them
    for you.


    > To answer why people recommend using "Easier to Ask Forgiveness than
    > Permission" as opposed to "Look Before You Leap" : Because of the way
    > it's implemented, Python works quite differently from most languages. An
    > attribute look-up is rather expensive because it's a hash table look-up
    > at run time. Wrapping a small piece of code in a try block however,
    > isn't (relatively) very expensive at all in Python.


    It's not just relatively inexpensive, it's absolutely inexpensive: it
    costs about as much as a pass statement in CPython, which is pretty much
    as cheap as it gets. (If anyone can demonstrate a cheaper operation
    available from pure Python, I'd love to see it.)


    > It's only catching the exception that's expensive,


    True.


    > but if you're catching the exception,
    > something has gone wrong anyway and performance isn't your biggest
    > issue.



    The second try...except clause in the urllib2 module reads:

    try:
    kind = int(kind)
    except ValueError:
    pass

    In this case, the error is simply ignored. Nothing has gone wrong.


    Here's an example from my own code: I have an API where you pass a
    mapping (either a dict or a list of (key, value) tuples) to a function.
    So I do this:

    try:
    it = obj.iteritems()
    except AttributeError:
    it = obj
    for key, value in it:
    do_stuff()



    There's nothing wrong with catching exceptions.


    --
    Steven
     
    Steven D'Aprano, Jan 1, 2010
    #10
  11. Peng Yu

    Lie Ryan Guest

    On 1/1/2010 3:47 PM, Peng Yu wrote:
    > I observe that python library primarily use exception for error
    > handling rather than use error code.
    >
    > In the article API Design Matters by Michi Henning
    >
    > Communications of the ACM
    > Vol. 52 No. 5, Pages 46-56
    > 10.1145/1506409.1506424
    > http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >
    > It says "Another popular design flaw—namely, throwing exceptions for
    > expected outcomes—also causes inefficiencies because catching and
    > handling exceptions is almost always slower than testing a return
    > value."
    >
    > My observation is contradicted to the above statement by Henning. If
    > my observation is wrong, please just ignore my question below.
    >
    > Otherwise, could some python expert explain to me why exception is
    > widely used for error handling in python?


    Simple, when an exception is thrown and I don't catch it, the exception
    terminates the program immediately and I got a traceback showing the
    point of failure. When I return error value and I don't check for it, I
    passed passed errors silently and gets a traceback forty-two lines later
    when trying to use the resources I failed to acquire forty-two lines prior.

    > Is it because the efficiency
    > is not the primary goal of python?


    Efficiency is not primary goal of python, but since python encourages
    EAFP (Easier to Ask Forgiveness than Permission); the design decisions
    chosen makes setting up a try-block much cheaper than a language
    designed over LBYL (Look Before You Leap) and return codes.
     
    Lie Ryan, Jan 1, 2010
    #11
  12. On Fri, Jan 1, 2010 at 9:49 AM, Steven D'Aprano
    <> wrote:
    >
    > Exceptions are *exceptional*, not "errors" or "unexpected". They are
    > exceptional because they aren't the "normal" case, but that doesn't mean
    > they are surprising or unexpected. Are you surprised that your "for x in
    > range(1000)" loop comes to an end? Of course you are not -- it is
    > completely expected, even though less than 1% of the iterations are the
    > last loop. The end of the sequence is EXCEPTIONAL but not UNEXPECTED.
    >


    Sorry if my word choice was confusing- I was trying to point out that
    in Python, you don't test errors for your typical conditions, but for
    ones that you know still exist but don't plan on occurring often.
     
    Benjamin Kaplan, Jan 1, 2010
    #12
  13. Peng Yu

    Mel Guest

    Steven D'Aprano wrote:

    > On Fri, 01 Jan 2010 02:43:21 -0800, Jonathan Gardner wrote:
    >
    >> On Jan 1, 12:43 am, (Aahz) wrote:
    >>> In article <>,
    >>> Benjamin Kaplan <> wrote:
    >>> >In Python, throwing exceptions for expected outcomes is considered
    >>> >very bad form [...]
    >>>
    >>> Who says that? I certainly don't.

    >>
    >> Agreed.
    >>
    >> int("asdf") is supposed to return what, exactly? Any language that tries
    >> to return an int is horribly broken.

    >
    >
    > [sarcasm]
    > No no, the right way to deal with that is have int("asdf") return some
    > arbitrary bit pattern, and expect the user to check a global variable to
    > see whether the function returned a valid result or not. That's much
    > better than catching an exception!
    > [/sarcasm]


    Or the other way around, as in C (I suspect the original ACM article assumed
    C.) Look at the legion of C library subroutines that return only 0 for good
    or -1 for bad, and do all their real work in side-effects (through pointers
    as function arguments.) Python is a big improvement: use the function
    return values for the payload, and push the out-of-band "omyghod" response
    into an Exception.

    Mel.
     
    Mel, Jan 1, 2010
    #13
  14. On Fri, 01 Jan 2010 11:02:28 -0500, Benjamin Kaplan wrote:

    > I was trying to point out that in
    > Python, you don't test errors for your typical conditions, but for ones
    > that you know still exist but don't plan on occurring often.


    I'm sorry, but that makes no sense to me at all. I don't understand what
    you are trying to say.


    You do understand that exceptions aren't just for errors? They are raised
    under specific circumstances. Whether that circumstance is an error or
    not is entirely up to the caller.


    try:
    n = mylist.index('fault')
    except ValueError:
    print "All is good, no fault detected"
    else:
    print "Your data contains a fault in position", n



    People get hung up on the idea that exceptions == errors, but they
    aren't. They *may* be errors, and that is one common use, but that
    depends entirely on the caller.


    --
    Steven
     
    Steven D'Aprano, Jan 1, 2010
    #14
  15. > You do understand that exceptions aren't just for errors? They are raised
    > under specific circumstances. Whether that circumstance is an error or
    > not is entirely up to the caller.


    I think that's a fairly narrow definition of the word error, and
    probably also the source of confusion in this thread.

    ISTM that there is a long tradition of giving different meaning to
    the word "error" in computing. For example, the Unix man pages
    list various conditions as "errors" purely by their outcome, and
    completely ignoring on whether the caller would consider the result
    erroneous - ISTM that a system call reports an "error" iff it is
    "unsuccessful".

    By that (common) usage of "error", it is a condition determined by
    the callee, not the caller (i.e. callee could not successfully
    complete the operation). In that sense, it is indeed equivalent
    to Python's usage of exceptions, which are also determined by the
    callee, and typically also in cases where successful completion is
    not possible. Whether these cases are "exceptional" in the word
    sense (i.e. deviating from the norm) would have to be decided by
    the application, again (which would set the norm).

    Regards,
    Martin
     
    Martin v. Loewis, Jan 1, 2010
    #15
  16. Peng Yu

    Peng Yu Guest

    On Thu, Dec 31, 2009 at 11:24 PM, Chris Rebert <> wrote:
    > On Thu, Dec 31, 2009 at 8:47 PM, Peng Yu <> wrote:
    >> I observe that python library primarily use exception for error
    >> handling rather than use error code.
    >>
    >> In the article API Design Matters by Michi Henning
    >>
    >> Communications of the ACM
    >> Vol. 52 No. 5, Pages 46-56
    >> 10.1145/1506409.1506424
    >> http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >>
    >> It says "Another popular design flaw—namely, throwing exceptions for
    >> expected outcomes—also causes inefficiencies because catching and
    >> handling exceptions is almost always slower than testing a return
    >> value."
    >>
    >> My observation is contradicted to the above statement by Henning. If
    >> my observation is wrong, please just ignore my question below.
    >>
    >> Otherwise, could some python expert explain to me why exception is
    >> widely used for error handling in python? Is it because the efficiency
    >> is not the primary goal of python?

    >
    > Correct; programmer efficiency is a more important goal for Python instead.
    > Python is ~60-100x slower than C;[1] if someone is worried by the
    > inefficiency caused by exceptions, then they're using completely the
    > wrong language.


    Could somebody let me know how the python calls and exceptions are
    dispatched? Is there a reference for it?
     
    Peng Yu, Jan 2, 2010
    #16
  17. Peng Yu

    Aahz Guest

    In article <>,
    Martin v. Loewis <> wrote:
    >
    >Notice that in cases where the failure may be expected, Python
    >also offers variants that avoid the exception:
    >- if you look into a dictionary, expecting that a key may not
    > be there, a regular access, d[k], may give a KeyError. However,
    > alternatively, you can use d.get(k, default) which raises no
    > exception, and you can test "k in d" in advance.
    >- if you open a file, not knowing whether it will be there,
    > you get an IOError. However, you can use os.path.exists in
    > advance to determine whether the file is present (and create
    > it if it's not).


    But you *still* need to catch IOError: someone might delete the file
    after the test. Figuring out how to deal with race conditions is one of
    the main reasons Alex Martelli advocates EAFP over LBYL.

    Of course, in the real world, you often end up wanting to do it both
    ways.
    --
    Aahz () <*> http://www.pythoncraft.com/

    Weinberg's Second Law: If builders built buildings the way programmers wrote
    programs, then the first woodpecker that came along would destroy civilization.
     
    Aahz, Jan 2, 2010
    #17
  18. Peng Yu wrote:
    > Could somebody let me know how the python calls and exceptions are
    > dispatched? Is there a reference for it?


    I'm not a Python expert, but I have read some parts of the implementation.
    Hopefully someone steps up if I misrepresent things here...

    In order to understand Python exception handling, take a look at various C
    function implementations. You will see that they commonly return a pointer
    to a Python object (PyObject*), even if it is a pointer to the 'None'
    singleton. So, a function in Python _always_ returns something, even if it
    is 'None'.

    If, at the C level, a function doesn't return anything (i.e. a C NULL
    pointer) that means that the function raised an exception. Checking this
    pointer is pretty easy, typically you check that, clean up and return NULL
    yourself. Further functions for manipulating the exception stack and
    declarations of exception types and singletons are found in pyerrors.h (in
    Python 2.5, at least).

    I mentioned an "exception stack" above, though I'm not 100% sure if that is
    the proper term. I think that exceptions can be stacked upon each other
    (e.g. an HTTPD throwing a high-level RequestError when it encounters a low-
    level IOError) and that that is also how the backtrace is implemented, but
    I'm not sure about that.


    Hopefully someone can confirm or correct me here and that it helped you.

    Cheers!

    Uli
     
    Ulrich Eckhardt, Jan 2, 2010
    #18
  19. Peng Yu schrieb:
    > On Thu, Dec 31, 2009 at 11:24 PM, Chris Rebert <> wrote:
    >> On Thu, Dec 31, 2009 at 8:47 PM, Peng Yu <> wrote:
    >>> I observe that python library primarily use exception for error
    >>> handling rather than use error code.
    >>>
    >>> In the article API Design Matters by Michi Henning
    >>>
    >>> Communications of the ACM
    >>> Vol. 52 No. 5, Pages 46-56
    >>> 10.1145/1506409.1506424
    >>> http://cacm.acm.org/magazines/2009/5/24646-api-design-matters/fulltext
    >>>
    >>> It says "Another popular design flaw—namely, throwing exceptions for
    >>> expected outcomes—also causes inefficiencies because catching and
    >>> handling exceptions is almost always slower than testing a return
    >>> value."
    >>>
    >>> My observation is contradicted to the above statement by Henning. If
    >>> my observation is wrong, please just ignore my question below.
    >>>
    >>> Otherwise, could some python expert explain to me why exception is
    >>> widely used for error handling in python? Is it because the efficiency
    >>> is not the primary goal of python?

    >> Correct; programmer efficiency is a more important goal for Python instead.
    >> Python is ~60-100x slower than C;[1] if someone is worried by the
    >> inefficiency caused by exceptions, then they're using completely the
    >> wrong language.

    >
    > Could somebody let me know how the python calls and exceptions are
    > dispatched? Is there a reference for it?


    The source?

    http://python.org/ftp/python/2.6.4/Python-2.6.4.tgz

    These are really deep internals that - if they really concern you - need
    intensive studies, not casual reading of introductionary documents. IMHO
    you shouldn't worry, but then, there's a lot things you seem to care I
    wouldn't... :)

    Diez
     
    Diez B. Roggisch, Jan 2, 2010
    #19

  20. > I mentioned an "exception stack" above, though I'm not 100% sure if that is
    > the proper term. I think that exceptions can be stacked upon each other
    > (e.g. an HTTPD throwing a high-level RequestError when it encounters a low-
    > level IOError) and that that is also how the backtrace is implemented, but
    > I'm not sure about that.


    Not exactly. In this scenario, the IOError exception gets caught, its
    entire traceback discarded, and an entirely new exception RequestError
    gets raised (that has no connection to the original IOError anymore,
    unless the httpd code explicitly links the two).

    Instead, the traceback objects are created for a single exception.
    They are essentially the same as the call stack, just in reverse
    order (so that you get the "most recent call last" traceback output).
    Each traceback links to a frame object, and a next traceback object.

    Regards,
    Martin
     
    Martin v. Loewis, Jan 2, 2010
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Finney

    confusion about Exception Mechanism

    Ben Finney, Jan 15, 2004, in forum: Python
    Replies:
    3
    Views:
    308
    Samuel Walters
    Jan 15, 2004
  2. Replies:
    3
    Views:
    365
    Ben Hutchings
    Dec 13, 2005
  3. Ralph A. Moeritz

    exception handling mechanism

    Ralph A. Moeritz, Apr 12, 2005, in forum: C Programming
    Replies:
    1
    Views:
    342
    Fred L. Kleinschmidt
    Apr 12, 2005
  4. Steven Woody

    Event Handling and Signal-Slot Mechanism

    Steven Woody, Jan 19, 2009, in forum: Python
    Replies:
    2
    Views:
    1,071
    Steven Woody
    Jan 20, 2009
  5. Rob Hoelz

    Best error handling mechanism?

    Rob Hoelz, Jun 5, 2007, in forum: Perl Misc
    Replies:
    3
    Views:
    98
    Lars Haugseth
    Jun 16, 2007
Loading...

Share This Page