4.4 ORM实现原理
2025-02-17
- ORM是Django框架的核心模块 想精进,思考下:使用ORM提供的接口,在下面方面
- 为什么创建的Model会自动拥有名称为id的主键
- 查询管理器是什么,又是怎么添加到Model中的
- QuerySet是什么样的结构
4.4.1 Python元类
类的类型是:type
Python中使用type确定对象的类型是比较常见的
type的一个重要功能:创建类
如何用type动态创建类
- type创建类需要接收三个参数
- 类的名称
- 父类的元组
- 属性字典
A = type('A',(),{})
print(A)- 例子
class A(object):
hello = 'World'
def fun(self):
return "Hello"可以通过type来实现,如下
def fun(self):
return "Hello"
A = type('A',(),{'hello':'World','fun':fun})- 通过type继承
B = type('B',(A,),{})
b = B()
b.fun()Python在创建类对象(不是类实例对象)的时候,首先会从当前的类定义中查询是否指定了元类,如果没有,则继续在父类中寻找指定的元类。如果在任何父类中都找不到元类的声明,就会上升到模块层次去查询。最终,如果还没有找到元类的声明,Python就会使用内置的type来创建这个类
在Python中
__new__()方法用来创建实例__init__()负责初始化实例
- 需要修改类的属性,就需要重写元类的
__new__()方法
class BBSMeta(type):
def __new__(cls, name, bases, attrs):
attrs['desc'] = lambda self: 'django bbs'
return type.__new__(cls, name, bases, attrs)
class A(metaclass=BBSMeta):
pass
a = A()
print(a.desc())首先需要知道,在Python中,__new__方法用来创建实例,__init__负责初始化实例。所以,如果要修改类的属性,就需要重写元类的__new__方法。它接收四个参数:需要实例化的类对象、类的名字、类继承的父类集合、类的属性字典。
可以看到,BBSMeta类继承自type,它可以作为一个元类使用,且它实现了__new__方法,并给类添加了desc方法。之后,类A指定元类为BBSMeta,所以,A的实例就有了desc方法。
4.4.2 Python描述符
描述符就是实现了描述符协议的对象,描述符协议包含三个方法:
__get____set____delete__只要实现了这三个方法中的任意一个,这个类对象就被称作描述符,且这个类对象的实例就有了一些特殊的特性
如何声明__get__(self, instance, owner):用于访问属性,返回属性的值 __set__(self, instance, owner):设置属性的值,不返回任何内容 __delete__(self, instance):用于删除属性,不返回任何内容
只实现了__get__方法的对象成为非数据描述符,这类描述符只能读取对象属性
同时实现了__get__和__set__方法的对象是数据描述符,可以实现对属性的读写
参考文档:微信读书: https://weread.qq.com/web/reader/6e4329007193f1e66e43129k37632cd021737693cfc7149