对原类例子的理解和注释
Topic source感谢!另外这个表达式写的真的很酷!
# 其实上面的这几行可以简化为一行 mappings = {k:v for k, v in attrs.items() if isinstance(v, Field)} 吧?
补充一下楼主的解释,Model类中__init__()方法中的super()函数是用来调用dict类的init函数的!这行代码至关重要:
class Model(dict, metaclass=ModelMetaclass):
括号中的dict说明Model继承自dict类,换句话说,Model类就是Python的字典类!
所以才有了下文的初始化方法:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
这完全等价于我们创建字典的初始化方法:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
继续简化,就变成了这样:
u = {'id': 12345,
'name': 'Michael',
'email': 'test@orm.org',
'password': 'my-pwd'}
是不是一下就看懂了呢(✪ω✪)
- 1
采蘑菇的lucas_688
第一部分 - 数据类型Fiedl类的定义
# 定义Field类,包含两个属性,分别是字段的名称name与类型column_type
# 类StringField继承自类Field,同样有两个属性name与类型column_type
# 同理类IntegerField继承自类Field,同样有两个属性name与类型column_type
第二部分 - 元类ModelMetaclass的定义
其实定义好的元类ModelMetaclass,仍然是调用type.__new__(cls, name, bases, attrs)函数去构造类对象,可以试下如下代码
不同的是type.__new__()构造出的类的属性就在__dict__下,但是ModelMetaclass将属性移到__mappings__下了
第三部分 - 生成Model的实例对象
核心在于:在运行__init__来生成实例对象前,调用元函数ModelMetaclass来生成类对象,用这个类对象再去生成实例对象。 根据ModelMetaclass代码可以知道,当类名称为Model时,直接返回原始的type.__new__(cls, name, bases, attrs), 如:type.__new__(type, 'Model', (dict, ), Model(id=12345, name='Michael'))
此处对于super()函数的理解还是不清楚
第四部分 - 生成User实例对象
总结User实例对象的创建步骤:
1. User类的创建1: User类继承了Model类,而Model类由元类ModelMetaclass定义类的生成,所以User类对象首先通过ModelMetaclass的type.__new__()构造生成
2. User类的创建2: 在ModelMetaclass的type.__new__()构造函数中,name和bases已经确认,而属性attr是根据输入的属性内容,由__new__构造出
3. User实例的创建1:User类继承了Model类,所以User通过Model的构造函数__init__生成属性的时候会把输入的(id=12345, name='Michael')转化为dict格式{'id': 12345, 'name': 'Michael'}
4. User实例的创建2: User实例的生成中要按照元类ModelMetaclass的定义生成,即生成__mappings__和__Table__等属性