On 8/28/2013 5:09 PM, Joe Junior wrote:
While designing a simple library, I found myself asking a
philosophical question: to check or not to check the parameter's
interface?

I think that, considering it is Python, the usual answer would be
"no", but here is the situation that got me thinking:

class Flock:

     def __init__(self):
         self.ducks= []

     def do_stuff(self):
         for duck in self.ducks:
             duck.quack()

class Duck:

     def quack(self):
         #quack-quack
         pass

f = Flock()
d = Duck()
f.ducks.append(d)
f.do_stuff()

Ok, no big deal there, the problem is if the user forgets to implement
the quack() method. The stack trace would complain that "duck.quack()"
is wrong, but that can happen hundreds of lines after the user
actually added the object to the Flock, and it can be hard to find out
what is happening and which object is wrong.

Of course I don't want to check isistance(), I like duck typing, but
should I check if hasattr() and callable() before adding to the
container? What is the pythonic way to deal with it? Am I worrying too
much ;-)?

You could underscore '_ducks' and add a .add_duck method with the checks you suggest. Or wrap 'duck.quack()' in try-except and log or warn (or even raise) on AttributeError or TypeError (not callable) with an informative message. Grepping for 'ducks.append(' will find all locations where a non-duck might have been added.

Depending on who the users will be, I might just not worry about it until an exception is raised. If you try to protect against everything that you might do wrong, you are on the road to madness, as the protection code might also be buggy. (Too much testing has the same problem ;-).

--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to