1

My work place has imposed a rules for no use of exception (catching is allowed). If I have code like this

def f1()
 if bad_thing_happen():
   raise Exception('bad stuff')
 ...
 return something

I could change it to

def f1()
  if bad_thing_happen():
    return [-1, None]
  ...
  return [0, something]

f1 caller would be like this

def f1_caller():
  code, result = f1(param1)
  if code < 0:
    return code
  actual_work1()
  # call f1 again
  code, result = f1(param2)
  if code < 0:
    return code
  actual_work2()
  ...

Are there more elegant ways than this in Python ?

Nick K
  • 19
  • 1
  • 5
    Tell your work place that I hate them. As far as elegant ways, well, that would have been exceptions.... What you're doing is good (it's much like c error codes, only better), but I'd return a tuple rather than a list. That way you can say success, result = f1(param) – JoshD Oct 06 '10 at 03:40
  • 16
    There are useful reasons to write C++ code without exceptions, but writing Python code without them is abject nonsense. Exceptions are absolutely fundamental to Python. I strongly recommend finding the nearest plastic bat, and hitting your destructively incompetent boss with it as many times as possible. – Glenn Maynard Oct 06 '10 at 03:41
  • 1
    I'm with Glenn on this one. Golf clubs are better though, same force applied on a smaller area. – dutt Oct 06 '10 at 03:46
  • ...or Dice.com/careers.stackoverflow.com/Moster etc... You career just took a nasty turn. Jump ship. The people in charge are obviously troglodytes. – Paul Sasik Oct 06 '10 at 03:52
  • 3
    Do you only have an imperative restriction, or is it accompanied by some sane reasons? If there are reasons, they would make a good addition to your question. "Why?" is a very wise zen question and triggers a specific state of mind. – jedi_coder Oct 06 '10 at 04:25
  • If they don't come around to understanding that exceptions are essential to coding in Python, you may be well advised to `raise NeedNewJob("Inappropriate coding constraint")`. Maybe they have a handler in place. – intuited Oct 06 '10 at 05:00
  • @JoshD - lists will unpack just as well as a tuple. But I would also suggest the tuple return, using the common ()-less syntax `return -1, None` or `return 0, something`. To me, this more clearly says "I mean to return two values" vs. "I am returning a 2-value data structure". – PaulMcG Oct 06 '10 at 06:24
  • I'm guessing this is an overreaction to http://en.wikipedia.org/wiki/Ariane_5_Flight_501 . "Exceptions caused rocket crash -> exceptions are bad." However, even if the Ariane 5 software team had adopted this policy, the crash still would have occurred, since it was caused by *ignorance* of exceptions, not the use of them. – PaulMcG Oct 07 '10 at 07:23

3 Answers3

3

Exceptions in python are not something to be avoided, and are often a straightforward way to solve problems. Additionally, an exception carries a great deal of information with it that can help quickly locate (via stack trace) and identify problems (via exception class or message).

Whoever has come up with this blanket policy was surely thinking of another language (perhaps C++?) where throwing exceptions is a more expensive operation (and will reduce performance if your code is executing on a 20 year old computer).

To answer your question: the alternative is to return an error code. This means that you are mixing function results with error handling, which raises (ha!) it's own problems. However, returning None is often a perfectly reasonable way to indicate function failure.

Seth
  • 45,033
  • 10
  • 85
  • 120
  • When this type of policy is implemented it's usually due to some phantom fears. Some "senior" dev at some time got bit by something and is now afraid of it and forcing the unreasonable fear. – Paul Sasik Oct 06 '10 at 03:55
1

Returning None is reasonably common and works well conceptually. If you are expecting a return value, and you get none, that is a good indication that something went wrong.

Another possible approach, if you are expecting to return a list (or dictionary, etc.) is to return an empty list or dict. This can easily be tested for using if, because an empty container evaluates to False in Python, and if you are going to iterate over it, you may not even need to check for it (depending on what you want to do if the function fails).

Of course, these approaches don't tell you why the function failed. So you could return an exception instance, such as return ValueError("invalid index"). Then you can test for particular exceptions (or Exceptions in general) using isinstance() and print them to get decent error messages. (Or you could provide a helper function that tests a return code to see if it's derived from Exception.) You can still create your own Exception subclasses; you would simply be returning them rather than raising them.

Finally, I would work toward getting this ridiculous policy changed, as exceptions are an important part of how Python works, have low overhead, and will be expected by anyone using your functions.

kindall
  • 178,883
  • 35
  • 278
  • 309
1

You have to use return codes. Other alternatives would involve mutable global state (think C's errno) or passing in a mutable object (such as a list), but you almost always want to avoid both in Python. Perhaps you could try explaining to them how exceptions let you write better post-conditions instead of adding complication to return values, but are otherwise equivalent.

Community
  • 1
  • 1