Python3基础教程:元类详解
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基础教程:元类详解相关推荐
- Python元类详解
文章目录 Python元类详解 Python谜团 元类的本质 调用一个类时发生了什么 再探元类 自定义元类 彩蛋:跳过python解释器 Python元类详解 元类比99%的用户所担心的魔法要更深,如 ...
- keyshot渲染图文教程_KeyShot渲染教程,KeyShot渲染基础教程步骤图文详解
KeyShot渲染教程,KeyShot渲染基础教程步骤图文详解 KeyShot渲染教程,在我们导入了项目之后,接着我们就要输出图片或者动画了.这里有许多动态的方式来完成,在开始渲染之前,我们来设置我们 ...
- Spring Boot 2.x基础教程:配置文件详解
在快速入门一节中,我们轻松的实现了一个简单的RESTful API应用,体验了一下Spring Boot给我们带来的诸多优点,我们用非常少的代码量就成功的实现了一个Web应用,这是传统的Spring应 ...
- python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__
了解元类之前,先了解几个魔术方法: __new__.__init__.__call__ __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪 ...
- java多线程教程_java 基础教程之多线程详解及简单实例
java 多线程详解 在这篇文章里,我们关注多线程.多线程是一个复杂的话题,包含了很多内容,这篇文章主要关注线程的基本属性.如何创建线程.线程的状态切换以及线程通信. 线程是操作系统运行的基本单位,它 ...
- vb net excel 剪贴板 粘贴_Excel零基础教程选项卡功能详解
Excel功能区详解 你了解[开始]选项卡吗? Excel的[开始]选项卡 应该是我们使用最多的选项卡了 开始中包含了粘贴板.格式刷. 填充桶.条件格式.序列等等实用功能 今天我们就从开始选项卡开始 ...
- Python基础教程:括号()[]{}详解
Python主要有三种数据类型:字典.列表.元组.其分别由花括号,中括号,小括号表示. 如: 字典:dic={'a':12,'b':34} 列表:list=[1,2,3,4] 元组:tup=(1,2, ...
- java object 详解_Java基础之Object类详解
类Object是类层次结构的根类.每个类都直接或者间接地继承Object类.所有对象(包括数组)都实现这个类的方法.Object类中的构造方法只有一个,并且是无参构造方法,这说明每个类中默认的无参构造 ...
- python变量详解_python基础教程-03-变量详解
变量就像一个小罐子,里面是存放着各种数据类型的数据,并且在程序运行过程中会发生变化.变量名在一个工作空间内是唯一的,通过变量的名字就能找到对应的数据. 变量的赋值 变量的赋值就可以理解为往小罐子里存放 ...
最新文章
- JavaScript权威设计--CSS(简要学习笔记十六)
- 执行插件超过2分钟超时错误,如何办?
- 使用Navicat for Oracle新建用户无法登陆(用户名大小写问题)
- 批量移动某目录下某类型的文件到指定的目录下
- hdu 3812 Sea Sky 深搜+剪枝
- Symbol的应用场景1
- 14004.xilinx自动打包image.ub脚本
- Extjs4.x (MVC)Controller中refs以及Ext.ComponentQuery解析
- android通知悬浮通知_Android通知直接回覆
- static数据的初始化
- BZOJ4598 [Sdoi2016]模式字符串 【点分治 + hash】
- 深圳计师需要全国计算机证吗,深圳入户需要什么技师证
- can总线程序讲解_详解CAN总线
- Windows下vc开发chrome浏览器工程的一点粗浅理解和封装
- vscode怎样新建项目和文件
- 学废了系列 - WebGIS vs WebGL图形编程
- Tensorflow in partice (lesson three) Course 3 Natural Language Processing in TensorFlow
- DUMN : Deep User Match Network for Click-Through Rate Prediction
- C++算法:最大回文子串---动态规划-----夹逼法----中心扩展法
- 【Grafana 了解、学习和使用】