exception handling in complex Python programs
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Wed Aug 27 12:52:18 EDT 2008
Lie a écrit :
> 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.
>
Hear hear...
More information about the Python-list
mailing list