Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python exception handling - How to do it pythonic?

I am still learning the Python programmimg language. I asked myself in terms of code exceptions, when it is neccessary to handle such situations in a pythonic way. I read a few times "you should never pass an error silently".

For example a little function:

def square(list_with_items):
    return [i**2 for i in list_with_items]

Is it neccessary to write an error-handler, if somebody passes a tuple as parameter? Or it is more senseful to do it, when I have to check the validation of user-input?

like image 714
user3147268 Avatar asked Dec 30 '13 18:12

user3147268


Video Answer


1 Answers

In the specific case of checking types, the "Pythonic" thing to do is not to check them. Unless there is a good reason, you should assume that the caller is passing in a sensible type (note: "sensible type" might be different from "the type you expect"), and do your best to return something sensible as well. If the caller passes in a type that isn't sensible, it's perfectly acceptable to let them deal with the consequences.

For example, someone might sensibly pass an iterator of Decimal numbers into your square function:

>>> from decimal import Decimal
>>> square(Decimal(line.strip()) for line in open("numbers.txt")
[Decimal("4.0"), Decimal("9.0"), ...]

And everything would work! But explicitly checking the types would make that use case more difficult.

And then, for example, if someone passes in something that isn't sensible, they can deal with the error:

>>> square(42)
…
TypeError: 'int' object isn't iterable

This error message will also (in a script) contain all the file names and line numbers necessary to debug the issue.

On the other hand, it is sometimes useful to explicitly check the arguments, when the caller might make a mistake with surprising consequences. For example, if you're writing a function which will exhibit very poor performance with a list because it expects a deque, then a check for if not isinstance(input, deque): raise TypeError("a deque must be used!") might be justified.

The name for this "method for dealing with types" is called Duck Typing.

like image 150
David Wolever Avatar answered Oct 28 '22 14:10

David Wolever