上篇文章中通过代码方式,重点讲解了:

  1. __new__和__init__之间的关系,前者是用来创建类实例,后者用来初始化类实例,它两配合使用,才完整生成一个类实例。
  2. object和type之间的关系,前者负责继承这块工作,后者负责类型定义这块工作。即所有的对象都起源于object,所有的对象最终都是type这个类型。

本文将重点介绍元类和元类的创建。

1.什么是元类

元类是创建类的类。如何理解这句话,先看以下代码:

class B():pass
b=B()
print(b.__class__)
print(B.__class__)
print(object.__class__)
#打印情况:
<class '__main__.B'>
<class 'type'>
<class 'type'>

上述代码中b是由类B构建的,因此b的类型(通过__class__属性查看)是<class ‘main.B’>,而后面B和object的类型都是type,同理,这说明B和object都是由type这个类创建的,即type可以用来创建类。
能够创建类的类,我们称作元类,type就是最原始的一个元类。

2.type如何创建类

首先声明:type在python中有两个身份:
1.type当做函数用,同__class__属性作用相同,返回对象的类型
2.type当做类用,是元类,用于创建其它的类。

下面是当做类用。
语法:

type(类名称字符串,类继承的元组,类的属性/函数字典)

三个的参数含义和类型都在上面规定了。下面代码用type类创建了一个类A,并为类A创建了一个name属性和一个show函数(注意不是shows函数,尽管定义的时候是shows)

def shows(self,name):print(name)
#用type类创建类A
A=type("A",(object,),{'name':"bob",'show':shows})
aa=A()
print(aa.name)
aa.show("wangwu")##输出结果
bob
wangwu

3.自定义元类

默认情况下,所有类都是由type元类创建,当然也可以自定义元类,这样该类的__class__属性就不是type了,而是该自定义元类。
语法:自定义元类必须要显示继承于type类。

class XXMetaClass(type):pass

4.设置类的元类为自定义元类

class XXClass(object,metaclass=XXMetaClass):pass

5.实例演练

下面代码中定义了一个元类TMetaclass,和三个普通类,且这三个普通类都是通过该元类生成的。由下面的打印结果可知,元类的__new__函数返回的值正是各个类。也就是说,在元类中是通过__new__函数生成类的。

class TMetaclass(type):def __new__(cls, name, bases, attrs):print("__new__参数:",cls, name, bases, attrs,'\n')print("__new__返回类型: ",type.__new__(cls, name, bases, attrs),'\n')return type.__new__(cls, name, bases, attrs)#生成相应的类,并返回class Test1(dict,metaclass=TMetaclass):def __init__(self, **kw):super(T, self).__init__(**kw)   def p(self):print("ppp")passclass Test2(Test1):passclass Test3(Test2):pass#结果打印:
__new__参数: <class '__main__.TMetaclass'> Test1 (<class 'dict'>,) {'__module__': '__main__', '__qualname__': 'Test1', '__init__': <function Test1.__init__ at 0x000002F08653E8C8>, 'p': <function Test1.p at 0x000002F08653E7B8>, '__classcell__': <cell at 0x000002F0864BA1C8: empty>} __new__返回类型:  <class '__main__.Test1'> __new__参数: <class '__main__.TMetaclass'> Test2 (<class '__main__.Test1'>,) {'__module__': '__main__', '__qualname__': 'Test2'} __new__返回类型:  <class '__main__.Test2'> __new__参数: <class '__main__.TMetaclass'> Test3 (<class '__main__.Test2'>,) {'__module__': '__main__', '__qualname__': 'Test3'} __new__返回类型:  <class '__main__.Test3'>

4.类实例的生成过程

分为两个阶段:
1.类的生成:由元类生成;
2.实例的生成:由上述生成的类接着生成。

具体描述

结合上一篇文章中,我们总结出生成一个类实例的全部过程:
1.类首先查找内部__metaclass__属性是否被自定义元类赋值,若赋值则准备用该自定义元类生成类,否则用type作为元类生成类;
2.解释器调用该元类的__new__函数(该函数为静态函数),并将要实例化的类中定义的各种属性传递给该函数固定的四个参数:其中cls是该元类本身,name是要被实例化的类的类名,bases是该类父类组成的元组,attrs则是该类{属性名:属性值,函数名:函数对象}组成的字典。
3.最终通过type类生成该类,并返回。
4.该类生成后,调用类中的__new__函数(该函数是静态函数)创建该类的实例,并返回该实例;
5.该实例接着调用它的__init__函数初始化实例,这样一个完整的实例就被生成出来了。

5,自定义元类的核心

由于是元类构建了类,因此若要更改某些固定类(str,int等)的用法,就必须在元类中做文章了。而元类的核心是__new__函数,自然在该函数内做文章。比如可以通过atrris字典为元类添加新的属性和函数,或改变以往的属性或函数等。这样的改变会传播到所有用该元类创建的类中。

总结:
__new__函数:
1.在元类中该函数用来构建类本身;
2.在类中,该函数用来构建类实例;

6. 类函数调用方式

def A():def show(self,name):print(name)
a=A()
#我们的调用方式:
a.show("hello")
#实际解释器的调用方式,这个a实例填充了self这个参数的位置
A.show(a,"hello")

参考文献:
1.深刻理解Python中的元类(metaclass)以及元类实现单例模式
2. 道生一,一生二
3. 一篇文章让你彻底搞清楚Python中self的含义

python--type,object,元类,__new__关系相关推荐

  1. python语法之元类与type()函数

    元类 千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三, ...

  2. 深刻理解Python中的元类(metaclass)以及元类实现单例模式

    在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对pyt ...

  3. Python中的元类及元类实现的单例模式

    https://www.cnblogs.com/tkqasn/p/6524879.html 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元 ...

  4. Python中的元类

    Python中的元类 Python一切皆对象,所以类也是对象. 我们知道,对象是通过类实例化创建出来的.但我们创建类时并没有进行实例化操作,为什么类也是对象呢? 类既然是对象,类肯定是另外某个类的实例 ...

  5. python中的元类Metaclass

    python中的元类Metaclass 理解元类之前需要学习的知识 如果说让我们创建一个类,最先想到的肯定是用class创建,当我们使用class创建类的时候,python解释器自动创建这个对象,但是 ...

  6. Python中的元类是什么?

    元类是什么,我们将它们用于什么? #1楼 请注意,此答案适用于2008年编写的Python 2.x,元类在3.x中略有不同. 元类是使"类"工作的秘诀. 新样式对象的默认元类称为& ...

  7. Python基础:元类

    一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...

  8. python中的元类_Python中的元类(metaclass)

    提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自身有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理 ...

  9. python最详细 ---- 元类 __metaclass__

    元类最常用作类工厂.就像通过调用类创建类的实例一样,Python通过调用元类创建一个新类(当它执行'class'语句时).结合常规__init__和__new__方法,元类因此允许您在创建类时执行&q ...

  10. python高级(元类、自定义元类)

    什么是元类(metaclass)? 元类是类的类,是类的模板 元类的实例为类,正如类的实例为对象 class Foo:      pass t1=Foo() #t1是通过Foo类实例化的对象 prin ...

最新文章

  1. EDM营销中HTML邮件设计方法和技巧
  2. 运维软件PE工具箱下载附制作、安装教程
  3. 重新学.Net[四]——效率和安全
  4. 参数详解 复制进程_如何优化PostgreSQL逻辑复制
  5. 深度学习TF—10.循环神经网络RNN及其变体LSTM、GRU实战
  6. k8s重要概念及部署k8s集群
  7. 分布式系统接口幂等性
  8. java学习第123天,p750-761(05/23)干得漂亮
  9. IOS-App Store 提审应用步骤
  10. Shopee本地店和跨境店物流及收款方式介绍
  11. 【直击DTCC】宝存CEO阳学仕:如何保障SSD的IO确定性?
  12. html 写字板 乱码,Win7系统写字板打开文档出现乱码的两种解决方法
  13. python中的if判断,和while循环的用法
  14. EXCEL多列内容合并且中间加字符串
  15. QPST 2.7.460 高通产品专用支持套件 (Qualcomm Product Support Tools)
  16. c3p0,DBCP,Druid(德鲁伊)数据库连接池
  17. linux下使用命令行来调节系统音量的两种方法amixer和pactl
  18. gcc 内联汇编用法介绍
  19. matlab时域计算频率,基于MATLAB 的信号时域采样及频率混叠现象分析
  20. php lodop,打印控件Lodop6.0版发布

热门文章

  1. mysql之两阶段提交
  2. spring中的控制反转和依赖注入之间的关系
  3. 【粉丝专享福利】联合6大博主送出18本ChatGPT扫盲教程实体书,文末有惊喜
  4. 整理的游戏服务器架构资料
  5. 失业3个月终于上岸,分享几点经验:不要转行,不要一份简历通吃,要重复投简历,要主动降薪!...
  6. JSON Schema 详解
  7. 程序员的nginx技能包(3)——静态资源管理,资源井井有条,生活风花雪月
  8. 内是不是半包围结构_半包围结构有什么字?
  9. js中复选框checkbox如何判定为被选中
  10. 阿里巴巴新零售数据库设计(简化版)