Should I use builtin exception or define my own? - python

I've method or function like:
findSomething(v)
Is appropriate to raise KeyError in the case I don't find anything or it's better to define my own exception? What do you think?
I know, it isn't strictly technical question, but they said: 'Readability counts' and I need to know what others think. :)

If the nature of the Error is complex, and its use also repeats in other places in your code I would define a custom Error.
Just cause it's more readable to write:
raise MyError('reason for MyError')
Than:
raise ValueError('the is an Error of type MyError, and here is the reason...')
But if it's not a repeatable part of your code, and the error is clear, I would use ValueError (before KeyError).

Might be closed as opinion-based, but.
I prefer to limit KeyError, ValueError etc to local scope, i.e no bigger than inside 1 function, preferably logical block inside.
Let's say you've caught a KeyError a couple layers from the original place the exception has taken place.
It gives you basically no information and could have happened basically anywhere.
A function calling another one shouldn't know about implementation details of the callee.
Also you're not writing a code to check exception stack trace and use it in your code logic, are you ?
Defining custom exception gives you the opportunity to describe location and high-level explanation of an issue like UserNotFound or NoMatchingChannel.
The code where you will catch it will give more insight about what is the issue and how to deal with it.

Well, I guess readability is more related to how you code, say how you name variables, functions, etc., how you structure your code and comment it.
But, regarding the exception handling question that you have: these are the things I think you should consider:
1- If the function gets a valid input and does not find anything you shouldn't throw or define an exception. You just need to return a value that represents you didn't find anything and/or just print a proper message.
2- If the input parameter, v, is invalid depending whether it is an object instantiated from a class or just a primitive type, you could define a proper exception for it or just catch a built-in exception, respectively.

Related

Should a function that normally returns list return a negative int on an exception?

If I have a function that reads a file and returns a list of values, but the file doesn't exist, or have read permissions set for the process, or any other kind of exception, is it better to:
let the exception happen organically
Try/catch the exception and print the error as a string, and return -1 or some other failure int
Try/catch the exception and print nothing, but return -1
Try/catch the exception and return the empty list (which is misleading)
Something else
In this case we are speaking of Python if it matters.
The answer is not really Python specific. A general rule about exceptions is that you should only catch them in the context where something can be done to recover from it: e.g. try again every 10 sec up to 3 times, where it makes sense, or ask the user what they want to do: retry, abort?
If the function catching the exception cannot recover sensibly, it is better to let the exception "bubble up". Sometimes, if the context catching the exception can add additional useful information, you can catch the exception, add meaningful information and re-throw a different, more meaningful exception. It really depends on what you are trying to do.
Note that returning an invalid value is a different paradigm of error handling and it makes sense in some situations, but in general, a failure like you describe is better handled through exceptions.
let the exception happen organically.
It's up to the caller to decide what to do, so give the caller the information it needs - the exception - and let it decide. Passing return codes just loses information, and is error-prone to boot.
If you can guarantee that the function will always be able to completely deal correctly with the exception then handle the exception in the function itself and return None on failure, since an empty list may be a valid return, and None is more Pythonic than an integer return code.
However, it's highly probably that you can't make such a guarantee, so you should allow the exception to bubble up to the caller. Or you may compromise by catching the exception, perform some analysis on it (possibly printing a warning message) and then re-raise the exception, or raise a modified version of it with extra error / warning information attached.
This is in accordance with the ancient programmer proverb:
Never test for an error condition that you don't know how to handle.
:)

Where to put exception handling in python

When using try/except blocks in Python, is there a recommendation to delegate it to any methods that might raise an exception, or to catch it in the parent function, or both?
For example, which of the following is preferred?
def my_function():
s = something.that.might.go_wrong()
return s
def main():
try:
s = my_function()
except Exception:
print "Error"
or
def my_function():
try:
s = something.that.might.go_wrong()
return s
except Exception:
print "Error"
def main():
s = my_function()
PEP 8 seems to be quiet on the matter, and I seem to find examples of both cases everywhere.
It really depends on the semantics of the functions in question. In general if you're writing a library, your library probably should handle exceptions that get raised inside the library (optionally re-raising them as new library-specific exceptions).
At the individual function level, though, the main thing you want to think about is what context/scope you desire to handle the exception in - if there is a reasonable different thing you could do in exceptional cases within the inner function, it might be useful to handle it within the inner function; otherwise, it might make more sense to handle it in the outer function.
For the specific case of writing output, it's often useful to only do that at the highest level, and inner functions only ever (a) return values or (b) raise exceptions. That makes the code easier to test because you don't have to worry about testing side effect output.
If you are following the rule of "one function should handle one task" then You shouldn't handle exception in that function, Let it fail loudly on unexpected input. Parent function which calling such function may handle to give better experience to user.
We can refer python builtin functions to get pythonic way
I always use the second one. Logically to me it seems that the problems of a function should be dealt with in that function only. This would provide user a clean and a hassle free interface, so you could later put your code in a library.
There could be some cases where you would want to use exceptions outside the function. For example if you want to print a particular message when something goes wrong then you should use the exception out of the function.
However you could provide the exception statements as a argument to the function if you want to give user the ability to decide his own exception message. So i guess the Second example(exception inside the function) would be universal and thus should be preferred.

Where's the standard python exception list for programmes to raise?

There is a list standard python exceptions that we should watch out, but I don't think these are the ones we should raise ourselves, cause they are rarely applicable.
I'm curious if there exists a list within standard python library, with exceptions similar to .NET's ApplicationException, ArgumentNullException, ArgumentOutOfRangeException, InvalidOperationException — exceptions that we can raise ourselves?
Or is there different, more pythonic way to handle common error cases, than raising standard exceptions?
EDIT: I'm not asking on how to handle exceptions but what types I can and should raise where needed.
If the error matches the description of one of the standard python exception classes, then by all means throw it.
Common ones to use are TypeError and ValueError, the list you linked to already is the standard list.
If you want to have application specific ones, then subclassing Exception or one of it's descendants is the way to go.
To reference the examples you gave from .NET
ApplicationException is closest to RuntimeError
ArgumentNullException will probably be an AttributeError (try and call the method you want, let python raise the exception a la duck typing)
AttributeOutOfRange is just a more specific ValueError
InvalidOperationException could be any number of roughly equivalent exceptions form the python standard lib.
Basically, pick one that reflects whatever error it is you're raising based on the descriptions from the http://docs.python.org/library/exceptions.html page.
First, Python raises standard exceptions for you.
It's better to ask forgiveness than to ask permission
Simply attempt the operation and let Python raise the exception. Don't bracket everything with if would_not_work(): raise Exception. Never worth writing. Python already does this in all cases.
If you think you need to raise a standard exception, you're probably writing too much code.
You may have to raise ValueError.
def someFunction( arg1 ):
if arg1 <= 0.0:
raise ValueError( "Guess Again." )
Once in a while, you might need to raise a TypeError, but it's rare.
def someFunctionWithConstraints( arg1 ):
if isinstance(arg1,float):
raise TypeError( "Can't work with float and can't convert to int, either" )
etc.
Second, you almost always want to create your own, unique exceptions.
class MyException( Exception ):
pass
That's all it takes to create something distinctive and unique to your application.
I seem to recall being trained by the documentation that it is ok to raise predefined exceptions, as long as they are appropriate. For example, the recommended way to terminate is no longer to call exit() but rather to raise SystemExit.
Another example given is to reuse the IndexError exception on custom container types.
Of course, your application should define its own exceptions rather than to actually repurpose system exceptions. I'm just saying there's no prohibition from reusing them where appropriate.
The Pythonic way is just let the exceptions pass through from Python itself. For example, instead of:
def foo(arg):
if arg is None:
raise SomeNoneException
bar = arg.param
Just do:
def foo(arg):
bar = arg.param
If arg is None or doesn't have the param attribute, you will get an exception from Python itself.
In the Python glossary this is called "EAFP":
Easier to ask for forgiveness than permission. This common Python coding
style assumes the existence of valid
keys or attributes and catches
exceptions if the assumption proves
false. This clean and fast style is
characterized by the presence of many
try and except statements. The
technique contrasts with the LBYL (Look Before You Leap)
style common to many other languages
such as C.
And it works well in tandem with Python's inherent duck typing philosophy.
This doesn't mean you should not create exceptions of your own, of course, just that you don't need to wrap the already existing Python exceptions.
For your own exceptions, create classes deriving from Exception and throw them when it's suitable.

Python: I'm not allowed to raise exception. Are there other elegant python ways?

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 ?
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.
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.
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.

python: Should I use ValueError or create my own subclass to handle invalid strings? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Which exception should I raise on bad/illegal argument combinations in Python?
I've looked through python's built in exceptions and the only thing that seems close is ValueError.
from python documentation:
exception ValueError:
Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.
Should I create a subclass of ValueError, like InvalidFormatException?
(My particular case is if a roman numeral string is improperly formatted, but there are many other applicable cases.)
EDIT: it seems like ValueError is the right choice, now the issue is whether to use ValueError directly or to subclass it.
ValueError is a good match for the case you have. Just go with that and remember that you can specify a useful message as an argument, letting you distinguish this from other types of ValueError.
I would not make the code more complicated by defining a subclass, however, unless I had a good reason to want to catch just that particular error but avoid catching any other ValueErrors. Many applications have dozens of "special" error conditions, but if they also defined per-case subclasses the code would quickly get unmaintainable and anyone trying to use the routines would be constantly surprised by the unexpected new exceptions.
ValueError seems logical:
In [1]: int('abc')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython console> in <module>()
ValueError: invalid literal for int() with base 10: 'abc'
I vote for creating a unique subclass, InvalidFormatException.
ValueError, while true, is vague.
InvalidFormatException is more specific and tied directly to your problem.
A user could wind up with situations where they're doing something that could produce either error. They could be converting roman numerals and then doing some math. They might need to distinguish between the ValueError and the InvalidFormatException.
Well really it depends whether you want (or need) that particular exception to be catchable independently of other ValueErrors that may occur during invocation of your code. It also depends whether you are the sole consumer of your code or it's intended for other people to use; in the latter case it may be helpful to these people if you define some high-level library-specific exceptions that they can check for.
Yes. ;-) ValueError does sound like the most applicable of the built-in ones, and with a subclass of that you seem to be doing the best possible. It's also what f.i. '%q' % 1 would raise.
I also support ValueError for this case. My 2 cents.

Categories

Resources