exception handling in complex Python programs

Lie Lie.1296 at gmail.com
Fri Aug 22 14:59:32 CEST 2008


On Aug 21, 12:59 am, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Wed, 20 Aug 2008 09:23:22 -0700, dbpoko... at gmail.com wrote:
> > On Aug 19, 4:12 pm, Steven D'Aprano <st... at REMOVE-THIS-
> > cybersource.com.au> wrote:
> >> On Tue, 19 Aug 2008 11:07:39 -0700, dbpoko... at gmail.com wrote:
> >> >   def do_something(filename):
> >> >     if not os.access(filename,os.R_OK):
> >> >       return err(...)
> >> >     f = open(filename)
> >> >     ...
>
> >> You're running on a multitasking modern machine, right? What happens
> >> when some other process deletes filename, or changes its permissions,
> >> in the time after you check for access but before you actually open it?
>
> > This is a good point - if you want to use the correct way of opening
> > files, and
> > you don't want to worry about tracking down exception types, then we can
> > probably
> > agree that the following is the simplest, easiest-to-remember way:
>
> >   def do_something(filename):
> >     try:
> >       f = open(filename)
> >     except:
> >       <handle exception>
>
> No, we don't agree that that is the correct way of opening files. Simple
> it might be, but correct it is not.
>
> If you're using Python 2.6 or greater, then you should be using a with
> block to handle file opening.
>
> And regardless of which version of Python, you shouldn't use a bare
> except. It will mask exceptions you *don't* want to catch, including
> programming errors, typos and keyboard interrupts.
>
> > Opening files is a special case where EAFP is the only correct solution
> > (AFAIK). I still liberally sprinkle LBYL-style "assert isinstance(...)"
>
> Oh goodie. Another programmer who goes out of his way to make it hard for
> other programmers, by destroying duck-typing.
>
> BTW, assertions aren't meant for checking data, because assertions can be
> turned off. Outside of test frameworks (e.g. unit tests), assertions are
> meant for verifying program logic:
>
> def foo(x):
>     # This is bad, because it can be turned off at runtime,
>     # destroying your argument checking.
>     assert isinstance(x, int)
>     # And it raises the wrong sort of exception.
>
>     # This is better (but not as good as duck-typing).
>     if not isinstance(x, int):
>         raise TypeError('x not an int')
>         # And it raises the right sort of error.
>
>     y = some_function(x)
>     # y should now be between -1 and 1.
>     assert -1 < y < 1
>     do_something_with(y)
>
> > and other similar assertions in routines. The point is that EAFP
> > conflicts with the interest of reporting errors as soon as possible
>
> Not necessarily. Tell me how this conflicts with reporting errors as soon
> as possible:
>
> def do_something(filename):
>     try:
>         f = open(filename)
>     except IOError, e:
>         report_exception(e)  # use a GUI, log to a file, whatever...
>
> How could you report the exception any earlier than immediately?

I'm sure different people would have different view on what
immediately means. The LBYL supporters define immediately as
immediately after a definite potential problem is detected (by ifs or
assertion), while the EAFP supporters define immediately as
immediately after a problem arises. No side is right or wrong, both
have weakness and strength, but python-style programs are encouraged
to use EAFP-style exception handling whenever feasible, but with the
spirit of the Zen: "Special cases aren't special enough to break the
rules, although practicality beats purity", if LBYL makes things much
easier in that case, and doing EAFP would just convolute the code,
then practicality beats purity.

> --
> Steven




More information about the Python-list mailing list