[Tutor] How to handle exceptions raised inside a function?

Steven D'Aprano steve at pearwood.info
Wed Dec 1 12:37:51 CET 2010


Patty wrote:
> This is very interesting to me - the below excerpt is something I was 
> trying to do for one of my programs and gave up on it:
> 
>> A fifth approach, common in some other languages, is to return some 
>> arbitrary value, and set an error flag. The caller then has to write 
>> code like this:
>>
>> result = function(arguments)
>> if not last_result_error:
>>     # no error occurred
>>     print "result is", result
>>
>>
>> If you do this, I will *personally* track you down and beat you to 
>> death with a rather large fish.
>>
>> *wink*
> 
> I think I was trying to do something like thius at the end of a function 
> I wrote-
> 
> return 2  or return my_special_integer_mvar

That syntax won't work. However, the basic idea is (moderately) sound: 
your function has a special value that means "something funny happened". 
Python very occasionally uses this:

 >>> "hello world".find("z")  # not found
-1

which you then use like this:

result = string.find(target)
if result == -1:  # special value
     print("not found")
else:
     print("found at position %d" % result)

In general, this idiom is mildly disparaged in Python circles, but not 
forbidden. Exceptions are usually considered better.

However, what I'm talking about is quite different. Here's how I might 
write the string find method using this (horrible) implementation:


# Global status flag.
find_succeeded = 0

def find(string, target):
     global find_succeeded
     if target in string:
         find_succeeded = 1
         return string.find(target)
     else:
         find_succeeded = 0
         # I never know what number to return...
         return 42  # that'll do...

(In low-level languages like C, the number returned on failure (where I 
choose 42) is often whatever value happens to be in some piece of memory 
-- essentially a random number.)


result = find("hello world", "z")
if find_succeeded == 1:
     print("found at position %d" % result)
else:
     print("not found")


This is even more inconvenient and difficult than earlier. Consider what 
happens if you want to do two or more searches. Because they all report 
their status via the one global variable, you must inspect the global 
after each call, before making the next call, or the status will be 
lost. In Python you can do this:

results = [s.find(target) for s in list_of_strings]

and then, later, inspect each individual result to see if it was -1 or 
not. But with the global status idiom, you can't do that, because the 
status flag is lost once you call find() again.



-- 
Steven



More information about the Tutor mailing list