说实话,我真心不太想总结这个东西,算了,炒一下egon的吧

1 引子

1 class Foo:
2 pass
3
4 f1=Foo() #f1是通过Foo类实例化的对象

python中一切皆是对象,类本身也是一个对象,当使用关键字class的时候,python解释器在加载class的时候就会创建一个对象(这里的对象指的是类而非类的实例)

上例可以看出f1是由Foo这个类产生的对象,而Foo本身也是对象,那它又是由哪个类产生的呢?

1 #type函数可以查看类型,也可以用来查看对象的类,二者是一样的
2 print(type(f1)) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建
3 print(type(Foo)) # 输出:<type 'type'>

2 什么是元类?

元类是类的类,是类的模板

元类是用来控制如何创建类的,正如类是创建对象的模板一样

元类的实例为类,正如类的实例为对象(f1对象是Foo类的一个实例Foo类是 type 类的一个实例)

type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象

3 创建类的两种方式

方式一:

1 class Foo:
2 def func(self):
3 print('from func')

方式二:

1 def func(self):
2 print('from func')
3 x=1
4 Foo=type('Foo',(object,),{'func':func,'x':1})

4 一个类没有声明自己的元类,默认他的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类(顺便我们也可以瞅一瞅元类如何控制类的创建,工作流程是什么)

 自定制元类
 自定制元类纯净版
 自定制元类精简版
 1 #元类总结
2 class Mymeta(type):
3 def __init__(self,name,bases,dic):
4 print('===>Mymeta.__init__')
5
6
7 def __new__(cls, *args, **kwargs):
8 print('===>Mymeta.__new__')
9 return type.__new__(cls,*args,**kwargs)
10
11 def __call__(self, *args, **kwargs):
12 print('aaa')
13 obj=self.__new__(self)
14 self.__init__(self,*args,**kwargs)
15 return obj
16
17 class Foo(object,metaclass=Mymeta):
18 def __init__(self,name):
19 self.name=name
20 def __new__(cls, *args, **kwargs):
21 return object.__new__(cls)
22
23 '''
24 需要记住一点:名字加括号的本质(即,任何name()的形式),都是先找到name的爹,然后执行:爹.__call__
25
26 而爹.__call__一般做两件事:
27 1.调用name.__new__方法并返回一个对象
28 2.进而调用name.__init__方法对儿子name进行初始化
29 '''
30
31 '''
32 class 定义Foo,并指定元类为Mymeta,这就相当于要用Mymeta创建一个新的对象Foo,于是相当于执行
33 Foo=Mymeta('foo',(...),{...})
34 因此我们可以看到,只定义class就会有如下执行效果
35 ===>Mymeta.__new__
36 ===>Mymeta.__init__
37 实际上class Foo(metaclass=Mymeta)是触发了Foo=Mymeta('Foo',(...),{...})操作,
38 遇到了名字加括号的形式,即Mymeta(...),于是就去找Mymeta的爹type,然后执行type.__call__(...)方法
39 于是触发Mymeta.__new__方法得到一个具体的对象,然后触发Mymeta.__init__方法对对象进行初始化
40 '''
41
42 '''
43 obj=Foo('egon')
44 的原理同上
45 '''
46
47 '''
48 总结:元类的难点在于执行顺序很绕,其实我们只需要记住两点就可以了
49 1.谁后面跟括号,就从谁的爹中找__call__方法执行
50 type->Mymeta->Foo->obj
51 Mymeta()触发type.__call__
52 Foo()触发Mymeta.__call__
53 obj()触发Foo.__call__
54 2.__call__内按先后顺序依次调用儿子的__new__和__init__方法
55 '''

python概念-其实只要简单了解一下,但是却讲了将近两个小时的知识点:元类的更多相关文章

  1. 神级程序员通过两句话带你完全掌握Python最难知识点——元类!

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

  2. python 内置函数的补充 isinstance,issubclass, hasattr ,getattr, setattr, delattr,str,del 用法,以及元类

    isinstance   是 python中的内置函数 , isinstance()用来判断一个函数是不是一个类型 issubclass  是python 中的内置函数,  用来一个类A是不是另外一个 ...

  3. 两句话掌握python最难知识点——元类

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

  4. 两句话掌握 Python 最难知识点——元类

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

  5. Python中对象、类型、元类之间的关系

    Python里的对象.类型和元类的关系很微妙也很有意思. 1989年圣诞节期间,上帝很无聊,于是创造了一个世界. 对象 在这个世界的运转有几条定律. 1.一切都是对象 对象(object)是这个世界的 ...

  6. Python与C的简单比较(Python3.0)

    Python可以说是目前最火的语言之一了,人工智能的兴起让Python一夜之间变得家喻户晓,Python号称目前最最简单易学的语言,现在有不少高校开始将Python作为大一新生的入门语言.本萌新也刚开 ...

  7. 零基础python之列表的简单介绍

    你点击关注,就分你小鱼干 一.概念:列表,由一系列按特定顺序排列的元素组成. 在 python 中,用 [ ] 方括号来表示列表,并用逗号来分割其中的元素. 二.访问列表因素 列表是有序集合,如要访问 ...

  8. Python常用的库简单介绍一下

    Python常用的库简单介绍一下fuzzywuzzy ,字符串模糊匹配. esmre ,正则表达式的加速器. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable ...

  9. Windows 下针对python脚本做一个简单的进程保护

    前提: 大家运行的脚本程序经常会碰到系统异常关闭.或被其他用户错杀的情况.这样就需要一个进程保护的工具. 本文结合windows 的计划任务,实现一个简单的进程保护的功能. 利用py2exe生产 ex ...

随机推荐

  1. php $_SERVER['HTTP_USER_AGENT']

    //获取浏览器 function getBrowse() { global $_SERVER; $Agent = $_SERVER['HTTP_USER_AGENT']; $browseinfo='' ...

  2. shell 指令 摘录

    作者: learner811    本文摘自网络    权限:用户 读写 ugoa rwx * useradd userdel groupadd groupmod usermod su sudo wh ...

  3. python调用docker API(CentOS6.5)

    一 环境背景 python-2.7.8 docker 版本 1.15 (*yum安装为1.14版本,需升级为1.15,详见后续步骤) 二 获取Docker容器指标[指标可行性分析见笔记:] CPU : ...

  4. JavaScript本地存储实践(html5的localStorage和ie的userData)

    http://www.css88.com/archives/3717 JavaScript本地存储实践(html5的localStorage和ie的userData) 发表于 2011年06月11日  ...

  5. java线程dump分析工具

    jstack和线程dump分析  java程序性能分析之thread dump和heap dump 一.[内存dump] jmap –dump:live,format=b,file=heap.bin ...

  6. BZOJ3277 串(后缀数组+二分答案+主席树)

    因为不会SAM,考虑SA.将所有串连起来并加分隔符,每次考虑计算以某个位置开始的子串有多少个合法. 对此首先二分答案,找到名次数组上的一个区间,那么只需要统计有多少个所给串在该区间内出现就可以了.这是 ...

  7. NOI2010~NOI2018选做

    [NOI2010] [NOI2010]海拔 高度只需要0/1,所以一个合法方案就是一个割,平面图求最小割. [NOI2010]航空管制 反序拓扑排序,每次取出第一类限制最大的放置,这样做答案不会更劣. ...

  8. 【CF888G】Xor-MST(最小生成树,Trie树)

    [CF888G]Xor-MST(最小生成树,Trie树) 题面 CF 洛谷 题解 利用\(Kruskal\)或者\(Prim\)算法都很不好计算. 然而我们还有一个叫啥来着?\(B\)啥啥的算法,就叫 ...

  9. CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)

    CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...

  10. 在ASP.NET MVC中对表进行通用的增删改

    http://www.cnblogs.com/nuaalfm/archive/2009/11/11/1600811.html 预备知识: 1.了解反射技术 2.了解C#3.0中扩展方法,分布类,Lin ...