来源:  码农翻身   作者:刘欣

隔壁的Java 世界为了创建一个对象搞得鸡飞狗跳,这边的Python解释器倒是乐得清闲。

我作为他的第n任助手正式上岗。

“老大,有程序员要创建对象,怎么办?”我向Python解释器发出了预警,上岗后头一次遇到这种情况,我有点紧张。

class Person:    def sayHello(self,name):        print('hello,'+name)

p = Person()

p.sayHello('andy')

“怕啥,我告诉你怎么做啊,首先找到Metaclass(元类),用元类来创建Class, 最后用Class对象来创建实例。”   老大说着还给我画了个图:

“不是吧!刚才还说人家Java鸡飞狗跳,我看我们这儿也丝毫不差,一个Class(如Person)在内存中用个对象来表示我理解,毕竟在我们的世界中,一切都是对象嘛, 但是这Metaclass(元类)是什么鬼?”

“是啊,类是一个对象,调用这个类对象的__new__方法就可以创建出这个类的实例。那么问题来了, 类对象是怎么来的?怎么把这个类对象给new 出来?”  老大没有回答,只是反问。

“不是程序员写的吗, class Person.....”  我有点底气不足。

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

“可是我也没有看到Person类的Metaclass啊?! 他到底在哪儿?”

“那是你没有找到, Person类中没有,就去它的父类中去找,如果也没有,就继续向父类的父类去找,如果在任何父类中都找不到Metaclass,就去模块中去找,如果还是找不到,就用缺省的Metaclass,即type。”

我按照老大的要求,去找这个Metaclass,没有找到,只好用缺省的type了。

可是我记得这个type不是个类,是个函数啊,可以用来查看一个变量的类型:

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

老大说:“这个type啊,还有另外一个用法,可以创建其他类对象,在创建的时候,需要三个参数:”

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

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

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

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

def sayHello(self,name):    print('hello,'+name)#通过type来创建一个类对象,名称为Person,这个类对象有一个方法sayHelloPerson = type('Person',(),{'sayHello':sayHello})#通过类对象来创建实例p = Person()p.sayHello('andy')  # hello andy

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

嘿,这个办法不错啊,可以在运行时、动态地创建一个全新的类出来!隔壁的Java虽然也能做到,但是得利用ASM之类工具去直接操作字节码,太麻烦了,我大Python直接通过普普通通、简简单单的Python代码就搞定了!

这就是动态脚本语言的一个优势吧!

之前听说过元编程,现在应该就是元编程了吧?但是这个Metaclass到底有什么用处呢? 程序员为什么不直接在代码中写class Person..... 这样的代码? 这样多直观啊。

老大说:“有些程序员会自定义Metaclass,这些自定义的Metaclass 主要做这些事情:”

1. 拦截类的创建

2. 读取类的信息,可能做修改

3. 返回新的类。

拦截类的创建? 为什么有这样“变态”的需求?

我真想看看一个自定义的Metaclass,看看它到底是怎么“变态”的。

没多久,机会来了,又要创建对象了。

from django.db import modelsclass Employee(models.Model):    name = models.CharField(maxlength = 50)        age  = models.IntegerField()    #其他代码略#

在Employee中没有看到Metaclass, 我就去父类Model中去寻找,运气不错,一下子就找到了metaclass ,叫做ModelBase:

class Model(metaclass=ModelBase):    #其他代码略

赶紧去看ModelBase的代码,唉,实在是有点复杂了,让我看得头晕。

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

“ORM?”

“就是对象和关系数据库的映射。你想想,程序员创建的Python对象想要保存到数据库中,该怎么办?“ 老大问道。

”那还不简单,程序员可以写SQL代码啊,insert into employee(name,age) values(?,?),其中包含那个Employee对象的name ,age的值不就行了?“

”那样就有点笨拙了,你再想想,能不能简化程序员的工作,别让他们去写这些烦人的、容易出错的SQL代码?能不能让框架来做这件事?“ 老大写了两行代码。

employee = Employee(name='andy',age=20)  employee.save()

“看看,程序员只要把对象创建出来,调用下save方法就行了,SQL语句就会形成,保存到数据库中。”

(注:这里略过了数据库连接的管理)

“难道ModelBase这个元类在后面做‘手脚'?”我似乎有点理解了。

”没错,你看到这些Employee类的属性没有? 就是程序员写的那些name, age...... 程序员这么写,其实就是在告诉ModelBase,尊敬的Metaclass 啊, 这些都是数据库的列啊,列名是 name, 类型是char(50) , 还有个列名是age,是个整数。”

“那个MetaClass ,对,就是ModelBase会读取这些列名、类型,并且记录下来。 有了列名的信息,将来就可以形成insert, update,delete等SQL语句了。对不对?”

原来如此!看来ModelBase在创建Employee类对象的时候,“偷偷地”读取了Employee类的定义信息,这样才能在背后实现ORM!

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

接下来又调用Employee类对象的__new__方法,创建了Employee实例对象。

employee = Employee(name='andy',age=20)  employee.save()

当程序员调用employee.save()方法的时候,正如老大所说,神奇的魔法发生了,一条sql语句形成,并且发送给了数据库去执行。

我感慨到:“这Python的元编程还是真是不错啊,能在运行时动态地修改类,比隔壁的Java强多了!”

“Python元编程的技术不仅仅是Metaclass,还多着呢,你慢慢学吧!”

深入浅出使用python编程_深入浅出Python元编程相关推荐

  1. 第一章 第一节:Python基础_认识Python

    Python基础入门(全套保姆级教程) 第一章 第一节:Python基础_认识Python 1. 什么是编程 通俗易懂,编程就是用代码编写程序,编写程序有很多种办法,像c语言,javaPython语言 ...

  2. python 网页编程_通过Python编程检索网页

    python 网页编程 The internet and the World Wide Web (WWW), is probably the most prominent source of info ...

  3. python元编程 实际应用_Python元编程

    简单定义"元编程是一种编写计算机程序的技术,这些程序可以将自己看做数据,因此你可以在运行时对它进行内审.生成和/或修改",本博参考<>将对元编程内容进行详细描述,若有不 ...

  4. 用python学编程_用Python学编程

    第1部分 引 论 第1章 关于本书 1.1 什么人要学编程 1.2 本书的内容 1.3 为什么选择Python 1.4 如何阅读本书 1.5 本书内容的组织 第2章 学习编程的要求 2.1 关于编程者 ...

  5. python2异步编程_最新Python异步编程详解

    我们都知道对于I/O相关的程序来说,异步编程可以大幅度的提高系统的吞吐量,因为在某个I/O操作的读写过程中,系统可以先去处理其它的操作(通常是其它的I/O操作),那么Python中是如何实现异步编程的 ...

  6. 学python编程_学习Python编程,我们应该如何学?学习内容包括哪些?

    点击蓝字"python教程"关注我们,一起学习成长哟! 我想可能很多网友和我有着相似的学习背景,学习Python会有以下的问题: 从零开始,不知道如何下手开始学? 被基本的数据结构 ...

  7. 第一门语言学python好_零基础学编程,哪一门语言比较适合入门?

    最近,有不少小伙伴问我,说零基础学编程,第一门语言学哪个好?有人推荐学Python,理由是Python简单,对新人友好,上手快,那Python到底适不合适新人学呢. 我今天就这个问题给大家稍微的展开一 ...

  8. python小型编程_学习Python编程的11个资源

    用 Python 写代码并不难,事实上,它一直以来都是被声称为最容易学习的编程语言.如果你正打算学习 web 开发,Python 是一个不错的选择,甚至你想学游戏开发也可 以从 Python 开始,因 ...

  9. python贺卡编程_一种卡片编程机及其编程方法与流程

    本发明涉及编程领域,特别涉及一种卡片编程机及其编程方法. 背景技术: 人工智能日趋火热,家长们也逐渐意识到孩子的培养方向,编程教育不仅为孩子的将来提前打下基础,而且还能够培养孩子的逻辑思维能力,优化孩 ...

最新文章

  1. 前端js判断上传是否为EXCEL表格问题
  2. CVPR 2020满分论文 | FineGym:面向细粒度动作分析的层级化高质量数据集
  3. 什么?超过60%的开发者都开始从Java 8 升级到 Java 11了?
  4. 聚类之isodata算法
  5. python cnn_使用python中pytorch库实现cnn对mnist的识别
  6. JavaScript世界的一等公民
  7. Linus Torvalds:回顾Linux20年
  8. html可视化布局工具_简介一些蜘蛛布局标签的饼图的绘制方法
  9. A-AUTOバッチ管理ツール(HOLD之后,如何再次启动)
  10. Grid Search 网格搜索 介绍
  11. 12306排队是什么意思_12306火车网上订票排队是什么意思
  12. python 串口接收多线程与界面通信_Python之PyQT多线程串口代码分析
  13. speedoffice(Word)文字怎么添加下划线
  14. java的流间隔问题_java – SuperMemo(SM-2)的间隔重复算法
  15. 福建2021高考成绩查询是什么时间,2021年福建高考成绩排名及成绩公布时间什么时候出来...
  16. 【SCENIC】Single Cell rEgulatory Network Inference and Clustering
  17. 华为数通笔记-文件传输协议FTP
  18. Postman批量参数化测试
  19. STM32F103---标准库函数驱动DS18B20
  20. python中幂函数_解决python中的幂函数、指数函数问题

热门文章

  1. 新浪微博技术架构分析-微博首席架构师杨卫华
  2. log4net进阶手札(三):保存日志到oracle中
  3. 【opencv450-samples】delaunay 三角剖分和 voronoi 细分
  4. 【学渣无能狂怒】今天也是为了学习落泪的一天--每天一遍Java再见
  5. 考研数学145分之路:暑期精读大学数学课本
  6. mysql workbench 6.3 ce 中文版_Mysql workbench
  7. 遥感影像处理的几个概念
  8. ios屏幕录制60帧_探索iOS屏幕帧缓冲区–内核反转实验
  9. 立创EDA仿真入门1 基本操作
  10. 单小说下载php,PHP 单TXT下载和多个TXT文件打包下载 同时