[Tutor] Decorators: Are they good for checking inputs and outputs?

Oscar Benjamin oscar.j.benjamin at gmail.com
Sun Jan 6 15:31:42 CET 2013


On 6 January 2013 12:30, DoanVietTrungAtGmail <doanviettrung at gmail.com> wrote:
> Dear tutors
>
> After much reading and head-scratching, I think the basic idea of decorators
> has now clicked for me. I am a beginner in programming and in Python, but I
> want to eventually develop a serious system. To spend most of my time on
> developing the ideas and building the code, I need to test my code fairly
> well but spend as little time doing so as possible. Therefore, I am looking
> ahead and thinking of using decorators extensively.
>
> Specifically, for every function I will write, I don't want to have to write
> code to check that arguments passed to it are of the permitted number, type,
> and range, then code to deal with those errors that can be dealt with. This
> is what I hope: Once I have collected or written all the necessary
> decorators, from then on I'll just routinely decorate each function with a
> whole bunch of decorators relevant to it.

Could you perhaps give a concrete example of a situation where a
decorator would be useful for checking the inputs to a function?

Unless you are writing many functions that accept the same number and
type of arguments, there isn't anyway to get around the fact that your
code needs to specify what each function expects. You can use helper
functions in the body of a function or decorators to wrap the function
from the outside but the effect in terms of code reuse and repeating
yourself is pretty much the same.

There are potentially other advantages to using decorators in this
context however. For example, with decorators it is easy to disable
checking at runtime for performance:

def checking_decorator(f):
    if DEBUG:
        # Wrap the function with a checking call
        def checking_wrapper(arg):
            if not valid(arg):
                raise SomeError
            return f(arg)
        return checking_wrapper
    else:
        # Return f directly (no performance penalty later)
        return f


Oscar


More information about the Tutor mailing list