(day38)元类+ORM
一、exec模块的补充
python的内置模块,可以把“字符串形式”的python代码,添加到全局名称空间或局部名称空间中
# 1. 对全局名称空间中的值进行修改
## 1. 文本形式的python代码
code = '''
global x
x=10
y=20
'''
## 2. 全局名称空间 {}
global_dict={'x':200}
## 3. 局部名称空间 {}
local_dict={}
exec(code,global_dict,local_dict)
print(global_dict)
# 2. 局部名称空间
## 1. 文本形式的python代码
code = '''
x=100
y=200
def func():
pass
'''
## 2. 全局名称空间 {}
global_dict={'x':200}
## 3. 局部名称空间 {}
local_dict={}
exec(code,global_dict,local_dict)
print(local_dict)
二、元类
(一)什么是元类
- python中一切皆对象,而类本质上也是另一个类实例化出来的对象,而这个类就叫做元类(简称类的类),内置的元类为type
- 元类可以控制类的创建
(二)通过class关键字创建类
class创建类时,内部会自动调用元类type,type会帮我们创建一个自定义类,此时会传入三个参数:
- 类名class_name
- class_bases = (object,)
- 类的名称空间class_dic,由执行类体代码得到的
(三)自定义元类控制类的创建
- 自定义创建元类:
- 自定义一个元类,继承type,派生出自己的属性和方法
- 通过metaclass指定自定义好的元类,来控制类的创建
- 通过元类type创建类,会在调用的时候(
__call__)做三件事:- 产生一个空对象
- 调用
__init__方法初始化对象obj - 返回初始化好的obj
class MyMeta(type):
# 控制对象的创建
# def __new__(cls,class_name,class_base,class_dic)
# 控制类的定义
def __init__(self,class_name,class_base,class_dic):
# 判断首字母是否大写
if not class_name.istitle():
raise TypeError ('类的首字母必须大写')
# 控制类中必须要有注释
if not class_dic.get('__doc__'):
raise TypeError('类内部必须要写注释')
# 模拟type元类内部做的事情
def __call__(self,*args,**kwargs):
# 1. 调用__new__创建一个空对象
obj = object.__new__(self)
# 2. 执行__init__(self,*args,**kwargs)
obj.__init__(*args,**kwargs)
return obj
class Foo(object,metaclass=MyMeta):
'''注释'''
x= 10
def __init__(self,a,b):
self.a = a
self.b = b
def f1(self):
print('f1')
foo = Foo(10,20) # 调用Foo对象,会触发__call__
print(foo.b)
三、ORM
ORM:对象关系映射,将类和数据库中的数据表进行映射
类名对应表名,对象对应记录,属性对应字段
这样可以通过对象.属性的方法直接访问到表数据,将数据库的增删改查全部封装成一个个函数
# 1. 字段类
## 1. 父类
class Field:
def __init__(self,name,type,primary_key,default):
self.name= name
self.type = type
self.primary_key = primary_key
self.default= default
## 2. 整形类
class Integer(Field):
def __init__(self,name,type='int',primary_key=False,default=0):
super().__init__(name,type,primary_key,default)
## 3. 字符串类
class String(Field):
def __init__(self,name,type='varchar',primary_key=False,default=None):
super().__init__(name,type,primary_key,default)
# 2. 元类
class OrmMetaClass(type):
def __new__(cls, class_name,class_bases,class_dic):
# 1. Models不用做判断,剔除掉Models类,
if class_name=='Models':
return type.__new__(cls,class_name,class_bases,class_dic)
# 2. 表名、主键、存储字段对象
table_name = class_dic.get('table_name',class_name) # 如果没有表名,类名做表名
primary_key = None
mappings = {} # 存储字段对象,防止,表记录对象.属性时触发不了__getattr__
# 3. 判断是否是唯一主键和必须要有主键,同时筛选出字段对象
for k,v in class_dic.items():
if isinstance(v,Field): # 判断是否是字段对象
mappings[k] = v # k是字段名,v是字段对象,v.name=k
if v.primary_key: # 如果字段对象中主键为真
if primary_key: # 默认primary_key为空,如果成立,说明,有两个主键
raise TypeError('只能有一个主键')
primary_key = k # k = v.name
# 4. 将类的内存空间中的的字段对象剔除,防止触发不了__getattr__,同时节省内存
for k in mappings.keys():
class_dic.pop(k)
# 5. 如果此时primary_key为空,说明没有主键
if not primary_key:
raise TypeError('必须要有一个主键')
# 6. 将主键名,表名,存储字段对象的字典存入类的名称空间
class_dic['table_name'] = table_name
class_dic['primary_key'] = primary_key
class_dic['mappings'] = mappings
# 7. 将修改好的名称空间,返回出去给__init__
return type.__new__(cls,class_name,class_bases,class_dic)
# 3. 表名父类
class Models(dict,metaclass=OrmMetaClass):
# 1. 对象.属性没有触发,返回字典取值,模仿对象中的属性
def __getattr__(self, item):
return self.get(item)
# 2. 对象.属性=赋值时触发,返回字典增加值,方便后续存储
def __setattr__(self, key, value):
self[key] = value
# 4. 用户表类
class User(Models): # 继承的dict,不需要设置__init__
user_id = Integer(name = 'user_id',primary_key=True)
user_name= String(name='user_name')
pwd = String(name='pwd')
u = User(user_id=1,user_name='wick',pwd='123')
print(u.user_id,u.user_name,u.pwd)
(day38)元类+ORM的更多相关文章
- 元类实现ORM
1. ORM是什么 ORM 是 python编程语言后端web框架 Django的核心思想,"Object Relational Mapping",即对象-关系映射,简称ORM. ...
- 使用元类 编写ORM
元类 一句话: 元类定制类的创建行为 知识点 1.类的创建: python这种动态语言,函数和类的定义,不是编译时定义的,而是运行时动态创建的. Python解释器遇到class定义时,仅仅是扫描一下 ...
- python——type()、metaclass元类和精简ORM框架
1.type()函数 if __name__ == '__main__': h = hello() h.hello() print(type(hello)) print(type(h)) Hello, ...
- 谈谈Python中元类Metaclass(二):ORM实践
什么是ORM? ORM的英文全称是“Object Relational Mapping”,即对象-关系映射,从字面上直接理解,就是把“关系”给“对象”化. 对应到数据库,我们知道关系数据库(例如Mys ...
- python ORM理解、元类
元类 参考链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143191 ...
- 04 -- 元类和ORM
本篇主要介绍元类,为什么说一切皆对象:如何动态的创建类等:以及ORM,即什么是ORM等知识 一.元类 1.1 在Python中一切皆对象 在学习元类中我们首先需要了解一个概念-- python中一切皆 ...
- Python元类实战,通过元类实现数据库ORM框架
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第19篇文章,我们一起来用元类实现一个简易的ORM数据库框架. 本文主要是受到了廖雪峰老师Python3入门教程的启 ...
- python-元类和使用元类实现简单的ORM
元类 面向对象中,对象是类的实例,即对象是通过类创建出来的,在python中,一切皆对象,同样,类也是一个对象,叫做类对象,只是这个类对象拥有创建其子对象(实例对象)的能力.既然类是对象,那么类是通过 ...
- 元类、orm
目录 一.内置函数exec 二.元类 1. 什么是元类 2. 元类的作用 3. 创建类的两种方法 4. 怎么自定义创建元类 三.ORM 1. ORM中可能会遇到的问题 2. ORM中元类需要解决的问题 ...
随机推荐
- C# git忽略文件 (.gitignore )
# Visual Studio # User-specific files *.suo *.user *.userosscache *.sln.docstates # User-specific fi ...
- package.json文件配置详解
package.json 是npm init命令初始化后,在项目的根目录下自动生成的配置文件,它定义了这个项目的配置信息以及所需要的各种模块,npm install根据这个命令,自动下载所需的模块.p ...
- POJ3662Telephone Lines(最短路+二分)
传送门 题目大意:n个点p条边,每条边有权值,让1和n点联通,可以将联通1--n的边选k条免费, 求剩下边权的最大值. 题解:二分一个答案x,大于x的边权设为1,小于等于x的边权设为0,跑最短路. 若 ...
- Reat学习笔记4
相信很多初学react的朋友在研究组件的路由配置问题时都很困扰,我也是折腾了半天才搞明白的. 一般情况下路由配置包含path和component两个信息: component顾名思义是组件的意思,指的 ...
- eclipse复制bpmn文件到idea下乱码问题处理
1.最近在学习工作流,在eclipse上画完了流程图,然后复制到idea下,发现节点的汉字是乱码的. 2.处理方案是修改idea的配置文件,如图,打开这两个文件,在文件末尾加上 -Dfile.enco ...
- Qt 删掉资源qss后报错
Error: dependent '..\..\........XXXX.qss' does not exist. 解决方案: 1.清理工程 2.qmake 3.重新构建
- 【SpringCloud之pigx框架学习之路 】2.部署环境
[SpringCloud之pigx框架学习之路 ]1.基础环境安装 [SpringCloud之pigx框架学习之路 ]2.部署环境 1.下载代码 git clone https://git.pig4c ...
- Wamp 下运行 CGI 笔记
虽然假期的余额不足了,但是仔细想想放假又有多少事情可以做呢?休息的差不多了,还是上班的好,长时间的休息人就废了.同意的举手,不同意的就算了. httpd.conf 的配置 我这里使用的是 Wamp 的 ...
- java、JavaScript获取微信用户信息登录优化方案
1.获取微信用户信息要调用微信的好几个接口,再加上自己系统的接口就会变的很慢,影响用户体验,之前走过的弯路我就不赘述了,直接说新的方案. 2.第一步都是向微信发起获取用户code请求: 请求接口:ht ...
- ASCll编码,