1. 通过__metaclass__实现自定义列表add方法:


1 class ListMetaclass(type): 2 """ 3 通过__metaclass__动态生成类,为新生成的类添加add方法 4 """ 5 6 def __new__(cls, *args, **kwargs): 7 """ 8 :param args: args包含了三个参数具体如下: 9 args[0]: 调用ListMetaclass的类名,这边为"MyList" 10 args[1]: 为MyList所继承的父类,这边为"(<type 'list'>,)" 11 args[2]: 为MyList类所包含的属性与方法, {'__module__': '__main__', '__metaclass__': <class '__main__.ListMetaclass'>} 12 :param kwargs: 13 :return: 返回后必须将这三个参数全部返回 14 """ 15 args[2]["add"] = lambda List, value: List.append(value) 16 return type.__new__(cls, *args) 17 18 class MyList(list): 19 __metaclass__ = ListMetaclass 20 21 c = MyList() 22 c.add(10) 23 print c
打印结果如下:
2. 通过__metaclass__实现ORM的save方法:


1 class Field(object): 2 def __init__(self, name, column_type): 3 self.name = name 4 self.column_type = column_type 5 6 def __str__(self): 7 return '<%s:%s>' % (self.__class__.__name__, self.name) 8 9 class StringField(Field): 10 def __init__(self, name): 11 super(StringField, self).__init__(name, 'varchar(100)') 12 13 class IntegerField(Field): 14 def __init__(self, name): 15 super(IntegerField, self).__init__(name, 'bigint') 16 17 class ModelMetaclass(type): 18 19 def __new__(cls, name, bases, attrs): 20 """ 21 :param name: 22 :param bases: 23 :param attrs: 这边attrs为User类中的数据属性,也就是每个变量对应一个文件类型的对象,具体如下: 24 { 25 'email': <__main__.StringField object at 0x0000000002827550>, 26 '__module__': '__main__', 27 'password': <__main__.StringField object at 0x0000000002827588>, 28 'id': <__main__.IntegerField object at 0x00000000028274E0>, 29 'name': <__main__.StringField object at 0x0000000002827518> 30 } 31 :param 在逻辑处理完成后, __mappings__数据为: 32 { 33 'password': <__main__.StringField object at 0x00000000028C75F8>, 34 'email': <__main__.StringField object at 0x00000000028C75C0>, 35 'name': <__main__.StringField object at 0x00000000028C7588>, 36 'id': <__main__.IntegerField object at 0x00000000028C7550> 37 } 38 :return: 39 这边的__metaclass__主要就是实现了对User类中文件对象的数据进行筛选,因为只有文件对象的数据才需要来拼接sql语句 40 """ 41 if name =='Model': 42 return type.__new__(cls, name, bases, attrs) 43 print('Found model: %s' % name) 44 mappings = dict() 45 for k, v in attrs.iteritems(): 46 #判断attrs中key对应的value是否为文件对象, 如果是则将对象赋值到mappings字典中 47 if isinstance(v, Field): 48 print('Found mapping: %s ==> %s' % (k, v)) 49 mappings[k] = v 50 51 # 先删除attr原先中文件对象,然后添加__mappings__方法,Model类中的save可以通过__mappings__中存放的文件对象来 52 # 实现数据的获取 53 for k in mappings.iterkeys(): 54 attrs.pop(k) 55 attrs['__mappings__'] = mappings # 保存属性和列的映射关系 56 attrs['__table__'] = name # 假设表名和类名一致 57 return type.__new__(cls, name, bases, attrs) 58 59 60 class Model(dict): 61 __metaclass__ = ModelMetaclass 62 63 def __init__(self, **kw): 64 super(Model, self).__init__(**kw) 65 66 def __getattr__(self, key): 67 try: 68 return self[key] 69 except KeyError: 70 raise AttributeError(r"'Model' object has no attribute '%s'" % key) 71 72 # def __setattr__(self, key, value): 73 # self[key] = value 74 75 def save(self): 76 fields = [] 77 params = [] 78 for k, v in self.__mappings__.iteritems(): 79 fields.append(v.name) 80 params.append(str(getattr(self, k, None))) 81 args = " (" 82 for i in params: 83 args += "'{}',".format(i) 84 sql = 'insert into %s (%s) values' % (self.__table__, ','.join(fields)) + args + ")" 85 print('SQL: %s' % sql) 86 87 class BoolObj(object): 88 pass 89 90 91 class User(Model): 92 id = IntegerField('uid') 93 name = StringField('username') 94 email = StringField('email') 95 password = StringField('password') 96 97 #这边User()实列化,由于User类继承了dict类,实际上就相当于dict(id=12345, name='Michael', email='test@orm.org', password='my-pwd') 98 #所有此时打印出来的u就是字典显示 {'email': 'test@orm.org', 'password': 'my-pwd', 'id': 12345, 'name': 'Michael'} 99 u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd') 100 u.save()
打印结果如下: