On Aug 21, 12:59 am, Steven D'Aprano <[EMAIL PROTECTED] cybersource.com.au> wrote: > On Wed, 20 Aug 2008 09:23:22 -0700, [EMAIL PROTECTED] wrote: > > On Aug 19, 4:12 pm, Steven D'Aprano <[EMAIL PROTECTED] > > cybersource.com.au> wrote: > >> On Tue, 19 Aug 2008 11:07:39 -0700, [EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list