python 元类的使用(orm框架搭建)
来源:互联网 发布:nba季后赛各项数据统计 编辑:程序博客网 时间:2024/06/05 10:28
元类是python面向对象编程里面很难理解的一个东西,所谓元类的就是类的类,它用来创建类,在python里面,类也是一个对象!!!.元类的作用就是动态的创建类.
在python里面type就是元类,我们所有的class定义类的语句都会被python解释为使用用type来创建一个类.
废话少说,首先看一下怎么用元类来解决一个动态创建类的需求,要求我们对于某一类型的类的满足某个条件的属性名字都变成大写!比如:
class test: a = 1 b = 2 c = 3
然后test里面的属性是A,B,C。当然这个需求比较奇怪,我们完全可以手动的把类属性定义为大写,但是如果对于类的动态创建要求比较高的话,自己定义类就会很麻烦.这个以后再说.
代码如下:
class TestMetaclass(type): def __new__(cls,name,bases,attrs): print(attrs) attr_names = [ (attr_name.upper(),value) for attr_name,value in attrs.items() if not attr_name.startswith('__')] print(attr_names) return super().__new__(cls,name,bases,attrs)class Test(dict,metaclass = TestMetaclass): f1 = 1 f2 = 2 sS = 3
这样得到的Test就是所有不以_开头的属性都是大写.而且除了Test,任何从TestMetaclass继承的类都是有这样的效果.
=====================我是分隔线========================
下面给出一种元类真正用的比较多的需求,构建ORM,ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句。
[0]首先需要构建顶层的接口.我们希望这个框架能够给我们提供这样的接口.
class User(Model): # 定义类的属性到列的映射: id = IntegerField('id') name = StringField('username') email = StringField('email') password = StringField('password')# 创建一个实例:u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')# 保存到数据库:u.save()
这样很方便,因为我可以随意创建其他的user1,user2等类,只需要调用相应的接口就可以执行相应的sql操作.但是这里就对orm框架有一个要求,我们的数据库的结构是不定的,可能另外的一个user1需要10个属性,user2需要8个属性,而且每个属性还不一样,这样你就必须让你的类在创建的时候执行一些你规定的操作,比如将所有的属性都收集起来,然后执行sql操作的时候在使用.简单的说就是抽象这些属性,让它们在orm框架中可以动态的创建和操作,而不是依靠属性的名字.
所以现在先构建Field类,它用来描述各个属性的名字和属性类型,比如id属性的名字就叫’id’,属性的类型就是’bigint’(我们自己定义的).
class Field(object): def __init__(self, name, column_type): self.name = name self.column_type = column_type def __str__(self): return '<%s:%s>' % (self.__class__.__name__, self.name)class StringField(Field): def __init__(self, name): super(StringField, self).__init__(name, 'varchar(100)')class IntegerField(Field): def __init__(self, name): super(IntegerField, self).__init__(name, 'bigint')
现在需要来编写orm框架的核心内容:元类的继承体系.
class ModelMetaclass(type): def __new__(cls,name,bases,attrs): if(name == 'Model'):#如果是Model类的话,就不需要做任何修改 return super().__new__(cls,name,bases,attrs) mappings = dict()#创建一个映射字典,用来存储当前创建的类的属性 for k,v in attrs.items():#遍历所有属性 if(isinstance(v,Field)):#注意k都是str,v才可能是Filed类型.用户定义的用来描述表的属性,需要修改.其他的属性不要乱动 print('Found mapping: %s ==> %s' % (k,v )) mappings[k] = v#把这个属性添加到mappings里面,同时删除attrs里面的属性,防止实例属性和类属性冲突 for k in mappings.keys(): attrs.pop(k) attrs['__mappings__'] = mappings#为attrs添加mappings这个属性,就是把所有自定义的属性都收集到attrs[__mapppings__] attrs['__table__'] = name#添加表的名字,这里偷个懒,表的名字就是类的名字 return super().__new__(cls,name,bases,attrs)class Model(dict,metaclass = ModelMetaclass): def __init__(self, **kw): super(Model, self).__init__(**kw) def __getattr__(self, key):#目的是让dict的keyerror变成attributeerror,因为使用getattr时处理的是AttributeError try: return self[key] except KeyError: raise AttributeError(r"'Model' object has no attribute '%s'" % key) def __setattr__(self, key, value): self[key] = value def save(self): fields = []#fields用来存储属性的名字 params = []#params用来 args = []#args用来 for k,v in self.__mappings__.items(): fields.append(v.name) params.append('?')#添加占位符 args.append(getattr(self,k,None))#将实例属性的值添加到args里面 sql = 'inser into %s (%s) value (%s)'%(self.__table__,','.join(fields),','.join(params)) print('SQL %s'%sql) print('ARGS %s'%str(args))
这样就完成了一个orm框架的初步结构
0 0
- python 元类的使用(orm框架搭建)
- 使用元类编写一个简单的ORM框架
- 利用元类编写简单的ORM框架
- Python的ORM框架SQLAlchemy
- Python的ORM框架-SQLAlchemy
- Python的ORM框架Peewee使用入门(一)
- Python的ORM框架Peewee使用入门(二)
- Python的ORM框架Peewee使用入门(三)
- Python的ORM框架SQLAlchemy使用入门(一)
- Python的ORM框架SQLAlchemy使用入门(三)
- python 学习笔记 元类 ORM
- python——type()、metaclass元类和精简ORM框架
- Django ORM框架的使用
- python sqlalchemy orm框架使用教程
- Python的数据库ORM框架:SQLAlchemy
- Python的数据库ORM框架:SQLAlchemy
- Python的ORM框架SQLAlchemy入门教程
- Python的数据库ORM框架:SQLAlchemy
- c++作业2
- linux教程:配置Tomcat开机启动 centos7
- 单例模式
- 对一个才子的走访我学到了什么?
- Aizu 0525(Osenbei 穷竭搜索)
- python 元类的使用(orm框架搭建)
- 克服当众表达的恐惧心理-《卡耐基语言的突破与相处的艺术》(美)卡耐基
- 【转载】在Windows下Memcache缓存系统构建(Java)
- android异步加载网络图片(1)
- 网络编程练习------简单双机通讯
- Launcher源码运行报错问题
- 匈牙利算法
- 采用dlopen、dlsym、dlclose加载动态链接库
- 产品经理养成计划之《缔造企鹅:产品经理是这样炼成的》读书笔记