Metaclasses help :-)

Antonio Cuni TOGLIMIcuni at programmazione.it
Thu Oct 31 20:52:41 CET 2002


sismex01 at hebmex.com wrote:

> I'm looking to create a metaclass which will check __init__'s
> keyword arguments *before* they're passed to __init__.

Perhaps this can help you:

class CheckInitArgs(type):
    def __new__(cls, bases, name, dic):
        try:
            init = dic['__init__']
            funcs = dic['__checkFunctions__']

            def ctor(self, *args):
                for f, arg in zip(funcs, args):
                    f(arg)
                init(self, *args)

            dic['__init__'] = ctor
        except KeyError:
            pass

        return super(CheckInitArgs, cls).__new__(cls, bases, name, dic)

def checkPositive(x):
    if x<=0:
        raise ValueError('Positive number expected')

def checkAlpha(s):
    if not s.isalpha():
        raise ValueError('Alphabetic word expected')

class Foo:
    __metaclass__ = CheckInitArgs

    def __init__(self, a, b):
        pass

    __checkFunctions__ = [checkPositive, checkAlpha]

if __name__ == '__main__':
    try:
        f = Foo(3, 'antonio')
    except ValueError, msg:
        print msg

    try:
        f = Foo(-3, 'antonio')
    except ValueError, msg:
        print msg

    try:
        f = Foo(3, 'antonio2')
    except ValueError, msg:
        print msg

It can be improved, of course: for example, you could add a better error 
handling, i.e. checking if number of arguments passed to __init__ equals 
to len(__checkFunctions__).

ciao Anto
-- 
"Computer science is not about computers any more than astronomy
is about telescopes." -- EW Dijkstra



More information about the Python-list mailing list