1.引入

Python中一切皆对象,所谓对象就是由类创建出来,那么创建对象的类本身也是一个对象,也就是说创建对象的类本身也由别的什么类创建,这种创建类的类就叫元类.

2.元类是谁?

type函数就是元类,没错就是那个打印数据类型的函数,也就是说是type创建了类.

我们写一个类然后打印一下他的属性看看

In [4]: class MyClass(object): ...:     pass ...:                                                                                           In [5]: type(MyClass)
Out[5]: type

可以看到MyClass类的类型是type,用Python语言来描述这种关系就是:

MyClass = type()

3.type和object的区别

刚接触元类时很容易搞混这两者.区别如下

type是说有类的创建者

object是所有类的父类

怎么理解呢?记住以下几点就OK了(可能有点绕)

  • type和object不是同一层的东西
  • type是元类object是普通类
  • 元类的对象是普通类,普通类的对象就是普通对象
  • 继承自object的类包括object本身都是普通类
  • 继承自type的类都是元类
  • 普通类都是元类的对象
In [9]: type(object)
Out[9]: type

那么是谁创建了type呢?这个问题留给你们自己去找答案,我相信有很多小伙伴已经猜到了.

4.通过type创建普通类

由type创建普通类的格式为

变量名 = type("类名", ("继承的类",), {"属性名":"属性值"})

第二个参数是元组类型

举个例子

In [11]: Myclass = type("ClassName", (object,), {"name": "kainhuck", "foo":"bar"})                In [12]: Myclass
Out[12]: __main__.ClassName

可以看到Myclass不是真正的类名,真正的类名是ClassName.

创建一个名为ClassA,继承自object类,并带有属性name和方法printName的类,写法如下

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
In [15]: def printName(self): ...:     print(self.name) ...:                                                                                          In [16]: ClassA = type("ClassA",(object,),{"name":"myName", "printName":printName})               In [17]: a = ClassA()                                                                             In [18]: a.printName()
myName

5.创建自己的元类

前面已经有过提示,我们可以通过继承type来创建自己的元类

举个例子:

In [20]: class MetaClass(type): ...:     pass ...:                                                                                          In [21]: ClassA = MetaClass("ClassA",(object,),{"name":"myName", "printName":printName})          In [22]: a = ClassA()                                                                             In [23]: a.printName()
myName

这个例子中我只继承type没有增加任何新的功能

我们知道创建一个对象的功能由__new__函数实现,下面我们通过修改__new__函数来创建一个必须含有printName方法的类.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
In [30]: class MyMetaClass(type): ...:     def __new__(cls, name, bases, attrs): ...:         func = attrs.get("printName", None) ...:         if not callable(func): ...:             raise NotImplementedError("必须创建一个名为 printName 的函数") ...:         return type.__new__(cls, name, bases, attrs) ...:          ...:                                                                                          In [31]: ClassA = MyMetaClass("ClassA",(object,),{"name":"myName", "printName":"not callable"})
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-31-772aa102a27f> in <module>
----> 1 ClassA = MyMetaClass("ClassA",(object,),{"name":"myName", "printName":"not callable"})<ipython-input-30-c2ffcc442a77> in __new__(cls, name, bases, attrs)3         func = attrs.get("printName", None)4         if not callable(func):
----> 5             raise NotImplementedError("必须创建一个名为 printName 的函数")6         return type.__new__(cls, name, bases, attrs)7 NotImplementedError: 必须创建一个名为 printName 的函数In [32]: ClassA = MyMetaClass("ClassA",(object,),{"name":"myName", "printName":printName})        In [33]:

可以看到如果我们定义的类没有创建printName函数就会报错.

6.类工厂

所谓类工厂就是生产类的地方,我们可以设计一个函数,使该函数可以通过参数来返回不同的类.

男人和女人都是人,但是不同性别的人剪头发的时间不一样.我们就可以定义一个类工厂来按需求产生不同的类.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def Person(sex):def manCut(self):print("我是男人,我剪头发很快")def womanCut(self):print("我是女人,我剪头发很慢")if sex == "man":return type("man", (object,), {"hairCut": manCut})elif sex == "woman":return type("woman", (object,), {"hairCut": womanCut})else:print("Error")Man = Person("man")
Woman = Person("woman")lilei = Man()
hanmeimei = Woman()

输出:

我是男人,我剪头发很快
我是女人,我剪头发很慢

Python3基础教程:元类详解相关推荐

  1. Python元类详解

    文章目录 Python元类详解 Python谜团 元类的本质 调用一个类时发生了什么 再探元类 自定义元类 彩蛋:跳过python解释器 Python元类详解 元类比99%的用户所担心的魔法要更深,如 ...

  2. keyshot渲染图文教程_KeyShot渲染教程,KeyShot渲染基础教程步骤图文详解

    KeyShot渲染教程,KeyShot渲染基础教程步骤图文详解 KeyShot渲染教程,在我们导入了项目之后,接着我们就要输出图片或者动画了.这里有许多动态的方式来完成,在开始渲染之前,我们来设置我们 ...

  3. Spring Boot 2.x基础教程:配置文件详解

    在快速入门一节中,我们轻松的实现了一个简单的RESTful API应用,体验了一下Spring Boot给我们带来的诸多优点,我们用非常少的代码量就成功的实现了一个Web应用,这是传统的Spring应 ...

  4. python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__

    了解元类之前,先了解几个魔术方法: __new__.__init__.__call__ __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪 ...

  5. java多线程教程_java 基础教程之多线程详解及简单实例

    java 多线程详解 在这篇文章里,我们关注多线程.多线程是一个复杂的话题,包含了很多内容,这篇文章主要关注线程的基本属性.如何创建线程.线程的状态切换以及线程通信. 线程是操作系统运行的基本单位,它 ...

  6. vb net excel 剪贴板 粘贴_Excel零基础教程选项卡功能详解

    Excel功能区详解 你了解[开始]选项卡吗? Excel的[开始]选项卡 应该是我们使用最多的选项卡了 开始中包含了粘贴板.格式刷. 填充桶.条件格式.序列等等实用功能 今天我们就从开始选项卡开始 ...

  7. Python基础教程:括号()[]{}详解

    Python主要有三种数据类型:字典.列表.元组.其分别由花括号,中括号,小括号表示. 如: 字典:dic={'a':12,'b':34} 列表:list=[1,2,3,4] 元组:tup=(1,2, ...

  8. java object 详解_Java基础之Object类详解

    类Object是类层次结构的根类.每个类都直接或者间接地继承Object类.所有对象(包括数组)都实现这个类的方法.Object类中的构造方法只有一个,并且是无参构造方法,这说明每个类中默认的无参构造 ...

  9. python变量详解_python基础教程-03-变量详解

    变量就像一个小罐子,里面是存放着各种数据类型的数据,并且在程序运行过程中会发生变化.变量名在一个工作空间内是唯一的,通过变量的名字就能找到对应的数据. 变量的赋值 变量的赋值就可以理解为往小罐子里存放 ...

最新文章

  1. JavaScript权威设计--CSS(简要学习笔记十六)
  2. 执行插件超过2分钟超时错误,如何办?
  3. 使用Navicat for Oracle新建用户无法登陆(用户名大小写问题)
  4. 批量移动某目录下某类型的文件到指定的目录下
  5. hdu 3812 Sea Sky 深搜+剪枝
  6. Symbol的应用场景1
  7. 14004.xilinx自动打包image.ub脚本
  8. Extjs4.x (MVC)Controller中refs以及Ext.ComponentQuery解析
  9. android通知悬浮通知_Android通知直接回覆
  10. static数据的初始化
  11. BZOJ4598 [Sdoi2016]模式字符串 【点分治 + hash】
  12. 深圳计师需要全国计算机证吗,深圳入户需要什么技师证
  13. can总线程序讲解_详解CAN总线
  14. Windows下vc开发chrome浏览器工程的一点粗浅理解和封装
  15. vscode怎样新建项目和文件
  16. 学废了系列 - WebGIS vs WebGL图形编程
  17. Tensorflow in partice (lesson three) Course 3 Natural Language Processing in TensorFlow
  18. DUMN : Deep User Match Network for Click-Through Rate Prediction
  19. C++算法:最大回文子串---动态规划-----夹逼法----中心扩展法
  20. 【Grafana 了解、学习和使用】

热门文章

  1. SCVMM 2012 R2运维管理十之:添加外围网络计算机
  2. 移植Python2到TQ2440
  3. cocosStudio制作ScrollView并在cocos2dx 3.0中使用。
  4. 【C语言探索之旅】第三部分第三课:SDL开发游戏之显示图像
  5. seajs的CMD模式的优势以及使用
  6. Memcached初探
  7. 【ABAP增强】基于函数的出口CMOD
  8. SAP 调用外部系统
  9. [基础语法] SEARCH搜索指定字符串详解
  10. 冲销已过账外向交货单