Python : should every function do it? Check the validity of the function parameters in
Should every Python function (or method) check the validity of its arguments?
Not just the type, if the value is within the valid range, is the size expected, etc.?
Or is it possible to just have “adult” well-behaved functions that simply expect from other functions, programmers, etc.? And mention what is expected in the docstring and simply check the validity of the user input parameter in the user-facing function?
In the case of the “private” method, it seems to me that we don’t need to check the validity, but what about other methods/functions?
If we’re too strict about this and check everything, wouldn’t the code be full of boring decorator-type code? Is that good?
Solution
Python encourages duck typing or “it’s easier to ask forgiveness than to ask permission” (EAFP), which means you should assume that your argument is correct, and if not, handle the situation properly.
We assume that “if it walks and talks like a duck, then it must be a duck”. Look here:
class Duck:
def quack(self):
return 'quack!'
class Person:
def quack(self):
return 'Hey there!'
d = Duck()
p = Person()
def make_it_quack(duck):
return duck.quack()
print(make_it_quack(d))
print(make_it_quack(p))
As you can see, both types work. This is a deliberate act. If you encounter something that does not define the method, you will get an AttributeError
as expected. The solution to this problem is to use exception handling:
try:
print(make_it_quack(d))
print(make_it_quack(p))
print(make_it_quack('hello world'))
except AttributeError:
print('object must have a "quack" method')
Having said all this, personally, I didn’t stick to it all the time. For example, if I can’t guarantee the type of my object, then I will use something like if isinstance(x, y)
to boot the code correctly. If not, try except
is returned.
It’s up to you to decide which one to choose to make your code clearer and suitable for the situation. There are suggestions for this, such as “always use try/except for IOErrors” (and for a reason).