data validation when creating an object

Skip Montanaro skip at pobox.com
Thu Jan 16 11:44:16 EST 2014


I suspect when best to validate inputs depends on when they
come in, and what the cost is of having objects with invalid
state. If the input is something that is passed along when
the object is instantiated, you kind of have to validate in
__init__ or __new__, right?

Let's create a stupid example:

class Point(object):
    def __init__(self, coordinates):
        self.x, self.y, self.z = coordinates

That's kind of self-validating. If you pass something that
doesn't quack like a three-element sequence, the program
will crash. OTOH, Point("abc") will appear to work until you
expect x, y and z to act like numbers. If you can't tolerate
that, then a __new__ method allows you to validate arguments
before creating a new Point instance. You might also allow
one- or two-element tuples:

    def __new__(cls, coordinates):
        ... convert to tuple, then ...
        ... verify that all elements are numbers, then ...

        if len(coordinates) > 3:
            raise ValueError("Expect 1-, 2-, or 3-element tuple")
        if len(coordinates) < 2:
            coordinates += (0.0,)
        if len(coordinates) < 3:
            coordinates += (0.0,)
	return cls(coordinates)

Validating in __new__ will allow you to catch problems
sooner, and give you the option of returning some sort of
sentinel instead of just raising an exception, though that
is probably not generally good practice. This will catch
Point("abc") quickly, with a stack trace pointing to the
offending code.

Of course, you might need to validate any other inputs which
appear after instantiation:

    def move(self, xdelta=0.0, ydelta=0.0, zdelta=0.0):
        self.x += xdelta
	self.y += ydelta
	self.z += zdelta

Whether you need more feedback than an exception might give
you here is debatable, but there are likely plenty of
situations where you need to explicitly validate user input
before using it (think of accepting string data from the net
which you plan to feed to your SQL database...). Those sorts
of validation steps are beyond the scope of this thread, and
probably much better handled by platforms further up the
software stack (like Django or SQLAlchemy).

Skip



More information about the Python-list mailing list