说实话,我真心不太想总结这个东西,算了,炒一下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. Android 开发工具下载中文网站

    Android官方网站(develop.android.com)因为被墙而无法访问.这时可以访问中文网址: http://wear.techbrood.com/ SDK Manager 代理及安装文件 ...

  2. 微信小程序组件 分页菜单点击请求

    //JS data: { navNum:0, navList: [ { id: 1, name: '已预约' }, { id: 2, name: '已消费' }, { id: 3, name: '已取 ...

  3. Memcache介绍与应用场景

    一:概念介绍         Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果 ...

  4. Java容器深入浅出之HashSet、TreeSet和EnumSet

    Java集合中的Set接口,定义的是一类无顺序的.不可重复的对象集合.如果尝试添加相同的元素,add()方法会返回false,同时添加失败.Set接口包括3个主要的实现类:HashSet.TreeSe ...

  5. python list类型的变量相当于全局变量 可以被函数与类引用

    python list类型的变量相当于全局变量 可以被函数与类引用

  6. P2236 [HNOI2002]彩票

    题目描述 某地发行一套彩票.彩票上写有1到M这M个自然数.彩民可以在这M个数中任意选取N个不同的数打圈.每个彩民只能买一张彩票,不同的彩民的彩票上的选择不同. 每次抽奖将抽出两个自然数X和Y.如果某人 ...

  7. 【ARC077F】SS

    Description 如果某个串可以由两个一样的串前后连接得到,我们就称之为"偶串".比如说"xyzxyz"和"aaaaaa"是偶串,而& ...

  8. BZOJ3522 [Poi2014]Hotel 【树形dp】

    题目链接 BZOJ3522 题解 就是询问每个点来自不同子树离它等距的三个点的个数 数据支持\(O(n^2)\),可以对每个距离分开做 设\(f[i][j]\)表示\(i\)的子树中到\(i\)距离为 ...

  9. oracle的学习笔记

    Oracle的介绍 1. Oracle的创始人----拉里•埃里森 2. oracle的安装 [连接Oracle步骤](](https://img2018.cnblogs.com/blog/12245 ...

  10. 模拟退火算法 R语言

    0 引言 模拟退火算法是用来解决TSP问题被提出的,用于组合优化. 1 原理 一种通用的概率算法,用来在一个打的搜索空间内寻找命题的最优解.它的原理就是通过迭代更新当前值来得到最优解.模拟退火通常使用 ...