Hi all, I have an API design question. I'm writing a function that can either succeed or fail. Most of the time the code calling the function won't care about the reason for the failure, but very occasionally it will.
I can see a number of ways of doing this, but none of them feel aesthetically pleasing: 1. try: do_something() except HttpError: # An HTTP error occurred except ApplicationError: # An application error occurred else: # It worked! This does the job fine, but has a couple of problems. The first is that I anticipate that most people using my function won't care about the reason; they'll just want a True or False answer. Their ideal API would look like this: if do_something(): # It succeeded else: # It failed The second is that the common path is success, which is hidden away in the 'else' clause. This seems unintuitive. 2. Put the method on an object, which stores the reason for a failure: if obj.do_something(): # It succeeded else: # It failed; obj.get_error_reason() can be called if you want to know why This has an API that is closer to my ideal True/False, but requires me to maintain error state inside an object. I'd rather not keep extra state around if I don't absolutely have to. 3. error = do_something() if error: # It failed else: # It succeeded This is nice and simple but suffers from cognitive dissonance in that the function returns True (or an object evaluating to True) for failure. 4. The preferred approach works like this: if do_something(): # Succeeded else: # Failed BUT this works too... ok = do_something() if ok: # Succeeded else: # ok.reason has extra information reason = ok.reason This can be implemented by returning an object from do_something() that has a __nonzero__ method that makes it evaluate to False. This solves my problem almost perfectly, but has the disadvantage that it operates counter to developer expectations (normally an object that evaluates to False is 'empty'). I know I should probably just pick one of the above and run with it, but I thought I'd ask here to see if I've missed a more elegant solution. Thanks, Simon -- http://mail.python.org/mailman/listinfo/python-list