
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