元类应用ORM实现
首先看下一个简单的例子
# 需求
import numbers class Field:
pass class IntField(Field):
# 数据描述符
def __init__(self, db_column, min_value=None, max_value=None):
self._value = None
self.min_value = min_value
self.max_value = max_value
self.db_column = db_column
if min_value is not None:
if not isinstance(min_value, numbers.Integral):
raise ValueError("min_value must be int")
elif min_value < 0:
raise ValueError("min_value must be positive int")
if max_value is not None:
if not isinstance(max_value, numbers.Integral):
raise ValueError("max_value must be int")
elif max_value < 0:
raise ValueError("max_value must be positive int")
if min_value is not None and max_value is not None:
if min_value > max_value:
raise ValueError("min_value must be smaller than max_value") def __get__(self, instance, owner):
return self._value def __set__(self, instance, value):
if not isinstance(value, numbers.Integral):
raise ValueError("int value need")
if value < self.min_value or value > self.max_value:
raise ValueError("value must between min_value and max_value")
self._value = value class CharField(Field):
def __init__(self, db_column, max_length=None):
self._value = None
self.db_column = db_column
if max_length is None:
raise ValueError("you must spcify max_lenth for charfiled")
self.max_length = max_length def __get__(self, instance, owner):
return self._value def __set__(self, instance, value):
if not isinstance(value, str):
raise ValueError("string value need")
if len(value) > self.max_length:
raise ValueError("value len excess len of max_length")
self._value = value
上述为属性描述符
元类的应用
class ModelMetaClass(type):
def __new__(cls, *args, **kwargs):
return super().__new__(cls, *args, **kwargs) class BaseModel(metaclass=ModelMetaClass):
def __init__(self,*args,**kwargs):
for key,value in kwargs.items():
setattr(self,key,value)
# return super().__init__() class User(BaseModel):
name = CharField(db_column="name", max_length=10)
age = IntField(db_column="age", min_value=1, max_value=100) class Meta:
db_table = 'user' if __name__ == "__main__":
user = User(name="bobby", age=28)
# user.name = "bobby"
# user.age = 28
# user.save()
print(user.name)
print(user.age)
print(user.Meta)
执行后结果:
bobby
28
<class '__main__.User.Meta'>
进一步改进代码:
class ModelMetaClass(type):
"""
name 类名
bases 基类(元组)
attrs:属性
还记得下面type生成类的使用方法吗?
User = type("User", (BaseClass, ), {"name":"user", "say":say})
"""
def __new__(cls, name, bases, attrs, **kwargs):
if name == "BaseModel":
return super().__new__(cls, name, bases, attrs, **kwargs)
fields = {}
for key,value in attrs.items():
if isinstance(value,Field):
fields[key] = value
attrs_meta = attrs.get('Meta',None)
_meta = {}
db_table = name.lower()
if attrs_meta is not None:
table = getattr(attrs_meta,'db_table',None)
if table is not None:
db_table = table
_meta['db_table'] = db_table
attrs['_meta'] = _meta
attrs['fields'] = fields
del attrs["Meta"]
return super().__new__(cls, name, bases, attrs, **kwargs) class BaseModel(metaclass=ModelMetaClass):
def __init__(self,*args,**kwargs):
for key,value in kwargs.items():
setattr(self,key,value)
# return super().__init__() class User(BaseModel):
name = CharField(db_column="name", max_length=10)
age = IntField(db_column="age", min_value=1, max_value=100) class Meta:
db_table = 'user' if __name__ == "__main__":
user = User(name="bobby", age=28)
# user.name = "bobby"
# user.age = 28
# user.save()
print(user.name)
print(user.age)
print(user._meta)
print(user.fields)
执行结果:
bobby
28
{'db_table': 'user'}
{'age': <__main__.IntField object at 0x0000000000C1F438>, 'name': <__main__.CharField object at 0x0000000000C1F3C8>}
元类应用ORM实现的更多相关文章
- Python 元类实现ORM
ORM概念 ORM(Object Ralational Mapping,对象关系映射)用来把对象模型表示的对象映射到基于 SQL 的关系模型数据库结构中去.这样,我们在具体的操作实体对象的时候,就不 ...
- 元类实现ORM
1. ORM是什么 ORM 是 python编程语言后端web框架 Django的核心思想,"Object Relational Mapping",即对象-关系映射,简称ORM. ...
- 使用元类 编写ORM
元类 一句话: 元类定制类的创建行为 知识点 1.类的创建: python这种动态语言,函数和类的定义,不是编译时定义的,而是运行时动态创建的. Python解释器遇到class定义时,仅仅是扫描一下 ...
- 04 -- 元类和ORM
本篇主要介绍元类,为什么说一切皆对象:如何动态的创建类等:以及ORM,即什么是ORM等知识 一.元类 1.1 在Python中一切皆对象 在学习元类中我们首先需要了解一个概念-- python中一切皆 ...
- 元类、orm
目录 一.内置函数exec 二.元类 1. 什么是元类 2. 元类的作用 3. 创建类的两种方法 4. 怎么自定义创建元类 三.ORM 1. ORM中可能会遇到的问题 2. ORM中元类需要解决的问题 ...
- python-元类和使用元类实现简单的ORM
元类 面向对象中,对象是类的实例,即对象是通过类创建出来的,在python中,一切皆对象,同样,类也是一个对象,叫做类对象,只是这个类对象拥有创建其子对象(实例对象)的能力.既然类是对象,那么类是通过 ...
- Python面向对象篇之元类,附Django Model核心原理
关于元类,我写过一篇,如果你只是了解元类,看下面这一篇就足够了. Python面向对象之类的方法和属性 本篇是深度解剖,如果你觉得元类用不到,呵呵,那是因为你不了解Django. 在Python中有一 ...
- 神级程序员通过两句话带你完全掌握Python最难知识点——元类!
千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
- Python中的元类
从前面"Python对象"文章中了解到,在Python中一切都是对象,类可以创建实例对象,但是类本身也是对象. class C(object): pass c = C() prin ...
随机推荐
- js转义和反转义html
本文地址: http://www.cnblogs.com/daysme/p/7100553.html 下面的代码网上常用有,但不是想要的. JS实现HTML标签转义及反转义 http://blog.c ...
- node.js 学习笔记一
2017-05-01 安装node 我没安装,下载即使用.要全局使用的话把node加入到环境变量中即可. 以下命令环境均为 cmd . 体验 体验一: 在命令行输入 node ,即进入 node 程序 ...
- 【NOI 2009】诗人小G
Problem Description 小 \(G\) 是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用 ...
- URAL 1004 Sightseeing Trip(floyd求最小环+路径输出)
https://vjudge.net/problem/URAL-1004 题意:求路径最小的环(至少三个点),并且输出路径. 思路: 一开始INF开大了...无限wa,原来相加时会爆int... 路径 ...
- windows 7 系统下,用户每次登录都是以临时配置文件的形式存在于users文件夹下
windows 7 系统下,用户每次登录都是以临时配置文件的形式存在于users文件夹下 当用户登录系统后,在users文件夹下创建的是一个临时文件夹,如果当前用户log off,那么当前用户的所有设 ...
- 安装Windows10系统注意事项
硬盘的AHCI开启: 报错解决:将Secure Boot 设置为Disabled win10系统下载地址:ed2k://|file|cn_windows_10_multi-edition_versi ...
- JAVA怎样理解面向对象
一.对象 现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,如人类.书桌.计算机.高楼大厦等.人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的.通常都 ...
- codeforces gym 100971 K Palindromization 思路
题目链接:http://codeforces.com/gym/100971/problem/K K. Palindromization time limit per test 2.0 s memory ...
- [C#][Windows]]基于ArcFace2.0+红外双目摄像头的活体检测
废话不多说 直接上图 这个是demo中用到的双目摄像头,一个是红外的,一个是正常的rgb摄像头两个usb接口,在电脑上呈现两路摄像头通道程序检测RGB输出图像,当检测到有人脸时,用RGB人脸的位置到红 ...
- Integer与int区别
Integer与int的区别:估计大多数人只会说道两点,一开始我也不太清楚,Ingeter是int的包装类,int的初值为0,Ingeter的初值为null.但是如果面试官再问一下Integer i ...