Decorator for validation - inefficient?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Nov 1 22:57:10 EDT 2008


On Sat, 01 Nov 2008 17:12:33 -0700, Bryan wrote:

> The list of validation error descriptions is returned instead of raising
> exceptions so clients can show the errors to the user for fixing.
> Raising exceptions seems like an uneeded burden for the client, as there
> is nothing exceptional about bad user input. 

But of course there is. Exceptional doesn't mean rare. In this case, it 
just means it's not the "normal" input which is expected.


> Instead, I want to raise an
> exception if a client actually tries to save an invalid entity back to
> the database. I will have to think on your suggestion a bit more before
> I am sure however.

As a general rule, every function should return one "kind" of thing. 
Notice I don't say "type", because it doesn't matter what the type/class 
of the data is, so long as it is conceptually the same sort of result.

E.g. a function that opens a connection to a database should *only* 
return a connection to a data, although the actual type of that 
connection may differ depending on the database. It shouldn't return 
either a connection or an error code.

I say that this is a general rule, because you can get away with breaking 
it, sometimes. E.g. string.find() returns either an offset or an error 
signal of -1. But note that this sometimes leads to bugs where people 
forget to check for a result of -1, and end up with code doing something 
unexpected.


You've suggested a usage:

"The list of validation error descriptions is returned instead of
raising exceptions so clients can show the errors to the user for
fixing."

But you can do that with an exception as well:

while True:
    try:
        validate(arguments)  # returns None on success, or raise Failure
        break
    except Failure, e:
        print e.msg
        for error in e.errors:
            print "You must fix this error: %s" % error
# when we exit the loop, the arguments are validated.
do_something_with(arguments)


If you're coming from a Java background, you may be concerned that 
exceptions are expensive. They aren't. Setting up the try...except block 
is very cheap. There's very little overhead to a try block that doesn't 
fail.


-- 
Steven



More information about the Python-list mailing list