Code前端首页关于Code前端联系我们

Python元编程技术剖析:不仅是元类

terry 2年前 (2023-09-25) 阅读数 48 #后端开发

“老大,程序员要创建一个对象怎么办?”我向 Python 解释器发送了预警。上班后第一次遇到这种情况,心里有些紧张。 班上的人:
def say Hello(我,名字):
print("hello,"+name)p = Person()

p.sayHello("andy")

什么,我来告诉你怎么做。首先找到元类(元类),用元类创建Class,最后用Class对象创建实例。”老大一边说着,一边给我画了一张图:

Python元编程技术解析:不仅仅是Metaclass

“不行!我刚才说Java会发疯。我想这里也没什么不同。类(例如Person)是由内存中的对象表示的。我明白了。毕竟,我们世界中的一切都是对象,但到底是什么?这是元类吗?”

“是的,类是一个对象,通过调用该类对象的 __new__ 方法可以实例化该类的实例。那么问题来了,类对象从哪里来?新的类对象是如何实现的? ?”老大没有回答,而是反问道。

“这不是程序员这个优雅的人写的……”我不确定。

“程序员写的只是代码,只是文本。我们在执行过程中需要使用Metaclass来创建这个Person类对象。”

“但我什至没有看到 Person 的元类。?!它在哪里?”

“那是因为你没有找到,如果Person类中没有,就在它的父类中查找,如果没有,就继续在父类的父类中查找。如果可以的话,如果可以的话在任何父类中都没有找到Metaclass,去模块中找到它。如果还找不到,就使用默认的Metaclass,即type。”

我按照老大的要求我搜索了这个元类,但找不到它,所以我不得不使用默认类型。

但我记得这个类型不是一个类,而是一个函数,可以用来检查变量的类型:

>>> type(1)
<class 'int'>
>>> type("aaa")
<class 'str'>
>>>

老大说:“这个类型还有另一个用处。它可以创建其他类对象。创建 When 后,需要三个参数:“

1.要创建的类对象的名称,例如“Person”

2。要创建的类的对象的父类,如(object,)

3。包含属性的字典,即类的属性和方法。例如{"sayHello": sayHello}

例如下面的代码也创建了一个Person类的对象,它和程序员写的Person类...的效果是一样的。

def sayHello(self,name):
    print("hello,"+name)

#通过type来创建一个类对象,名称为Person,这个类对象有一个方法sayHello
Person = type("Person",(),{"sayHello":sayHello})

#通过类对象来创建实例
p = Person()

p.sayHello("andy")  # hello andy 

(友情提示:可以左右滑动)

嘿,这是个好主意。您可以在 运行时动态创建新类 !虽然Neighbor Java可以做到这一点,但是你必须使用ASM之类的工具来直接操作字节码,这太麻烦了。我的Python高手直接通过简单明了的Python代码就可以做到!

这就是动态脚本语言的优点之一!

以前听说过元编程,现在应该是元编程吧?但是这个元类有什么用呢?为什么程序员不直接将代码写为 Person 类......在代码中?如此直观。

老大说:“有些程序员定制了元类,这些定制的元类主要做以下事情:”

1。创建拦截类

2。阅读班级信息,即可编辑

3。返回一个新类。

创建听力课程?为什么会有这样“变态”的要求呢?

我很想看看自己的元类,看看它到底有多“变态”。

没过多久,机会来了,又到了创作物品的时候了。 GFrom Django.db 导入类 Employee Models (Models.model):
name = Models.Charfield (MAXLENGTH = 50) Age = Models.Integerfield ()
#全集♻ #❙♻♻♻♻ did没有看到我是 Employee 中的元类,所以我去父模型类中寻找它。运气好,立刻找到了一个叫ModelBase的元类:类模型(metaclass=ModelBase):
#其他代码省略

赶紧看ModelBase代码。不幸的是,这有点复杂,让我头晕。

老大说:“不用花时间,你的前任的前任曾经研究过它,实现ORM !”

“ORM?”

“这是关于对象和关系的。数据库映射。想想如果你想将 程序员 创建的 Python 对象存储在数据库中,你会做什么?”老大问道。

“这不容易啊,程序员可以写SQL代码,将values(?,?)插入到employee(name,age)中,其中包含Employee对象的name和age值,对吧?”

“那个会有点笨拙。再想一想,你能让程序员的工作变得更轻松,不再要求他们编写这些烦人的、容易出错的 SQL 代码吗?你能允许框架这样做吗?”老大写了两行代码。 employee = Employee(name="andy",age=20)
employee.save()

"看,程序员只需要创建一个对象,调用save方法,就会创建SQL语句并保存到数据库中。”

(注意:此处跳过数据库连接管理)

“ModelBase 元类是否在幕后进行任何‘伪造’操作?”我似乎明白了一些。

”对了,你看到这些员工类的属性了吗?是名字,年龄……程序员写的其实是ModelBase,亲爱的Metaclass,这些是数据库列名是name,类型是char(50),列name是age,是一个整数。”

Python元编程技术解析:不仅仅是Metaclass

“这个MetaClass,是的,ModelBase会读取这些列名和类型,并记录下来,以后更新、删除等SQL命令。不会吧?”

就是原来如此!看来ModelBase在创建Employee类对象时,“偷偷”加载了Employee类的定义信息,从而可以在幕后实现ORM!

Python元编程技术解析:不仅仅是Metaclass

我按照老大的指示,调用了ModelBase的__new__方法创建Employee类对象。

接下来调用Employee类对象的__new__方法创建一个Employee实例对象。employee=employee(name="andy",age=20)
employee。 save()

当程序员调用employee.save()时,正如老大所说,奇迹发生了,SQL语句被创建并发送到数据库执行。

我感叹,“Python的元编程真好,可以动态地动态修改类,比隔壁的Java好太多了!”

“Python中的元编程技术不仅仅是Metaclass。还有很多,慢慢学吧!”

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门