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