Metaclass programming in Python learning

Class is how to generate

Class is how to generate? This problem is certainly silly. Actually not the case, many people only know to create a class using inheritance surface form, but do not know the real creates its interior by type to create.

type? This is not to determine an object type of function?

Yes, type common usage is used to determine the type of the object. But beyond that, his biggest use is used to dynamically create a class. When scanning Python syntax to class and they will call the type function to create a class.

 How to create a class type

First, type () requires three parameters


13717038-63adb2ba8779305a.png

Look at an example


13717038-0cc530e41e8b0bba.png


Understand what metaclass

What is class? Probably everyone knows, is used to create objects of class "template."

So what is the metaclass it? Word Popular, metaclass is creating a class of "template."

Why type can be used to create a class? Because it itself is a meta-class. Metaclasses create a class, it is a reasonable.

Python type is behind all the classes used to create the meta-class, we know from the ancestor object class type is created. What is more, even the type created by myself own type, which is excessive.


13717038-fd300ab1780c2807.png

If you want the image to understand, then, to see the following three jargon.

1str: to create a string object class.

2int: integer is used to create the object's class.

3type: class is used to create the object's class.

Conversely

One example of a type, a class

A type 2 class, metaclass

Type 3 metaclass is the type

Look at the examples


13717038-a54eac798fa16d85.png

The above is a simple example.

Let's look at a slightly more complete


13717038-53c10d2d58fdf991.png


Use the significance yuan class

Under normal circumstances, we will not use the yuan class. But that does not mean it is not important. If one day, we need to write a framework that is likely to need to use metaclasses.

But why should it do? What will it do?

After my summary, the following role in the process metaclass

Creating interception class

After the interception, the modified

After modification, the return type modified

Obviously, the use of meta class, the class is to be custom modifications. Use metaclass to dynamically generate the instance of a metaclass, while 99% of developers do not need to dynamically modify the class, because this should be the only thing to consider framework.

But, say, you will not be convinced, in the end metaclass used to do? In fact, the role is to create metaclass API, one of the most typical application is the Django ORM.

Metaclass combat: ORM

Used Django ORM knows, with ORM, allows us to operate the database, is easier than ever.

ORM的一个类(User),就对应数据库中的一张表。id,name,email,password 就是字段。


13717038-34d33fd15d36719a.png

如果我们要插入一条数据,我们只需这样做


13717038-630380efe3fe375c.png

通常用户层面,只需要懂应用,就像上面这样操作就可以了。

但是今天我并不是来教大家如何使用ORM,我们是用来探究ORM内部究竟是如何实现的。我们也可以自己写一个简易的ORM。

从上面的User类中,我们看到StrField和IntField,从字段意思上看,我们很容易看出这代表两个字段类型。字段名分别是id,username,email,password。

StrField和IntField在这里的用法,叫做属性描述符,如果对这个不了解的可以查看文章底部的参考文章,也是我写的。

简单来说呢,属性描述符可以实现对属性值的类型,范围等一切做约束,意思就是说变量id只能是int类型,变量name只能是str类型,否则将会抛出异常。

那如何实现这两个属性描述符呢?请看代码。


13717038-3c169583d94ee114.png

我们看到User类继承自BaseModel,这个BaseModel里,定义了数据库操作的各种方法,譬如我们使用的save函数,也可以放在这里面的。所以我们就可以来写一下这个BaseModel类


13717038-d6b5b3957424e6a3.png

从BaseModel类中,save函数里面有几个新变量,

fields: 存放所有的字段属性

db_table:表名

注意:上面代码中class BaseModel(metaclass=ModelMetaClass)请替换成class BaseModel(object) 再阅读。这样更贴合思考顺序。

我们思考一下这个u实例的创建过程:

type -> object -> BaseModel -> User -> u

这里会有几个问题。

Init parameters are passed when the User instance, the incoming type int id, name is str type. It looks nothing issue, and if so, I am above data descriptor becomes ineffective, can not tie function. So we hope init received id is IntField type, name is StrField type.

At the same time, we hope that these field properties, can be automatically sorted into fields variable. Because, as BaseModel, it is not specifically for the User class services, it also is compatible with a wide variety of table. Different tables, table has a different number of fields of different properties, these categories and must be able to automatically classify and organize together. This is a basic ORM framework.

We hope to have two options on the table name, if one is User Meta information specified in, such as the table name, used this as a table name, if not specified it as the class name in lowercase table names. Although BaseModel can take directly to the User's db_table property, but if the business logic in the database, the addition of this complex logic, apparently very elegant.

Above these questions, in fact, it can be accomplished by __new__ function yuan class.

Not the same metaclass __new__ and normal class, metaclass __new__, you can get to all the properties and methods of the upper class, including the class name, the magic method.

The general category of __new__ can only get to the outside world when instantiating properties passed.

Here's a look at how to use metaclasses to solve these problems? Look at the code.


13717038-f9206ddb51092b87.png

At this point, our simple ORM has been formed.

Reproduced in: https: //www.jianshu.com/p/44a860bcd275

Guess you like

Origin blog.csdn.net/weixin_33739627/article/details/91059763