class TypeSetter(object):

    def __init__(self,fieldtype):

        print 'TypeSetter set attribute type',fieldtype
        self.fieldtype = fieldtype

    def is_valid(self,value):

        print "TypeSetter is_valid is called"
        return isinstance(value,self.fieldtype)

class TypeCheckMeta(type):

    def __new__(cls,name,bases,dict):

        print '-'*29
        print 'Allocating memory for class'
        print name
        print bases
        print dict
        print '*' * 29
        return super(TypeCheckMeta,cls).__new__(cls,name,bases,dict)

    def __init__(cls,name,bases,dict):

        cls._fields = {}
        for key,value in dict.items():
            print '$'*8,key,'>'*8,value
            if isinstance(value,TypeSetter):
                cls._fields[key]=value

class TypeCheck(object):

    __metaclass__ = TypeCheckMeta

    def __setattr__(self, key, value):

        print 'TypeCheck set attribute value',key,value

        if key in self._fields:
            if not self._fields[key].is_valid(value):
                raise TypeError('Invalid type for field')

        super(TypeCheck,self).__setattr__(key,value)


class MetaTest(TypeCheck):

    name = TypeSetter(str)
    num = TypeSetter(int)

if __name__ == '__main__':

    mt = MetaTest()
    mt.name = "apple"
    mt.num = "test"

输出:

/home/python/.virtualenvs/company_web/bin/python /home/python/project/datacollecting/spider/test_reg.py
-----------------------------
Allocating memory for class
TypeCheck
(<type 'object'>,)
{'__module__': '__main__', '__metaclass__': <class '__main__.TypeCheckMeta'>, '__setattr__': <function __setattr__ at 0x7f2bad626c80>}
*****************************
$$$$$$$$ __module__ >>>>>>>> __main__
$$$$$$$$ __metaclass__ >>>>>>>> <class '__main__.TypeCheckMeta'>
$$$$$$$$ __setattr__ >>>>>>>> <function __setattr__ at 0x7f2bad626c80>
TypeSetter set attribute type <type 'str'>
TypeSetter set attribute type <type 'int'>
-----------------------------
Allocating memory for class
MetaTest
(<class '__main__.TypeCheck'>,)
{'__module__': '__main__', 'num': <__main__.TypeSetter object at 0x7f2bad624a50>, 'name': <__main__.TypeSetter object at 0x7f2bad624a10>}
*****************************
$$$$$$$$ __module__ >>>>>>>> __main__
$$$$$$$$ num >>>>>>>> <__main__.TypeSetter object at 0x7f2bad624a50>
$$$$$$$$ name >>>>>>>> <__main__.TypeSetter object at 0x7f2bad624a10>
TypeCheck set attribute value name apple
TypeSetter is_valid is called
TypeCheck set attribute value num test
TypeSetter is_valid is called
Traceback (most recent call last):
  File "/home/python/project/datacollecting/spider/test_reg.py", line 65, in <module>
    mt.num = "test"
  File "/home/python/project/datacollecting/spider/test_reg.py", line 51, in __setattr__
    raise TypeError('Invalid type for field')
TypeError: Invalid type for field

Process finished with exit code 1

results matching ""

    No results matching ""