一、元类
1. python:一切皆对象
- 类是一个对象
- 类似print()和input()等函数,为什么可以直接使用?因为python解释器运行起来后默认加载了个模块,这个模块被称为内建模块(或 内嵌模块) 。
- globals():(得到当前所有的全局变量。它是一个字典,键是变量名,值是它的引用对象)
- print(num)实际上是这样一个过程。要把num的引用传入print函数内部,先在globals的这个字典里遍历键,直到找到一个键为num的,然后找到其值。那么问题来了,字典中并没有print,是怎么找到print指向的函数的呢?
- 上面的字典中有一个键In,来记录所有输入的值。还有一个键Out,来记录所有输出的值。(ipython独有)
- 如果在ipython中输入的需要保存,怎么办? 方法1,把In里面的值复制。方法2,ipython背后有一个sqlite数据库,用sql语句查找出来。
- 内建函数里有什么:
- 当在globals中找不到时,它就会拿着
__builtin__
键,去其引用所对应的变量字典里找(就是 global_dict["__builtin__"].__dict__ 这个字典)
2. 元类创建类
- 元类是一种特殊的类,用来创建类
- 元类是python中的造物主(上帝)
- 怎么创建地创建一个实例对象? 方法1,用class。方法2,用元类(就像上面拐着弯用print函数一样的思想)。方法3,如下:
- 上面的方法太low了,有一个方法可以动态地创建类:type 。(由于向后兼容的历史遗留问题,type函数有两个功能,它最原始的功能就是动态创建类)
- type(类名, 父类元组,内部字典)
- 用help函数查看,可以发现type不是一个函数,而是一个类。这个类就叫做元类 。
- 用class定义类,其实是默认调用type。
3. 元类是一切的创建者
- 元类是深度的魔法。
- 如果想搞清楚是否需要用到元类==>那么一定用不到
- 用到元类的人都清楚他们需要做什么,并且不需要解释为什么使用元类。
4. 使用元类
- 运行上述代码一定出错。(并没有Num,只有num)原因是执行到class时,自动调用了type,把属性写入了。
- 解决方法: 不调用type来创建,调用自己写的东西来创建就好了。metaclass这个参数可以帮助我们。(它的缺省值为type)
- 这不是调用了函数来创建嘛?那怎么能称之为元类?
- 比如私有属性的改名,就是通过元类。
二、ORM
1. ORM是什么
- python中用到元类的场景少之又少。功能上相当于类的装饰器。
- ORM是Django框架的核心思想。即 对象-关系映射
- 类名–>表名;类属性–>每一个字段
操作类就是操作一张表
insert into 表名 (key1, key2, key3) values (1,2,3);
# >>>>>>>>>>相当于:>>>>>>>>>>
u = 表名(key1=1, key2=2, key3=3)
u.save
2. ORM实现
name = “key”
value = 7
self.name = value==>只会创建一个self.name=7
setattr(self, name, value)==>会创建 “key” = 7