一个案例深入Python中的__new__和__init__
来源:互联网 发布:金融数据库有什么后果 编辑:程序博客网 时间:2024/04/27 18:13
准备
在Python中,一切皆对象。
既然一切皆对象,那么类也是对象,我们暂且称之为 类对象。来个简单例子(本篇文章的所有案例都是运行在Python3.4中):
class foo(): passprint(id(foo)) print(type(foo))# 结果:# 46627056# <class 'type'>
如果想深入了解一下,可以看:深刻理解Python中的元类(metaclass)
引入
最近在阅读tornado源码,发现在其源码中有很多类是这样的:
class HTTPServer(TCPServer, Configurable, httputil.HTTPServerConnectionDelegate): def __init__(self, *args, **kwargs): # Ignore args to __init__; real initialization belongs in # initialize since we're Configurable. 就是说默认的__init__初始化方法不在起作用了,改为了initialize方法进行初始化 pass
或者是干脆没有__init__ ,只写了个initialize方法来替代。
所以心生疑惑,tornado是如何做到这一点的?
正题
接下来我们来了解一下,Python解释器是如何创建对象的。
大家可能对Python中的__init__方法很熟悉,认为他是实例化类时调用的第一个方法。但其实他并不是。实例化时调用的第一个方法其实是__new__方法。
好了,接下来是重点:
1 当我们实例化A类对象时,Python中首先调用的是该A类对象的__new__方法,如果该A类对象没有定义__new__方法,则去父类中依次查找,直到object类
2 object类有一个__new__方法,该方法接收一个参数(一般为类对象),将该参数进行实例化并返回一个对象
3 Python解释器会将调用__new__方法并将A类对象作为第一个参数传入,最后会返回一个对象(这个对象就是A类的实例对象,我们称之为a1)
4 Python解释器默认会调用a1对象的__init__方法,并将参数传入。
来一个例子验证一下:
class asd(object): def __new__(cls, *args, **kwargs): print('asd.__new__() is running. cls id is %s'%id(cls)) r = super(asd,cls).__new__(cls) print('r_id is %s'%id(r)) return rclass bnm(asd): def __init__(self,name): print('bnm.__init__() is running, self id is %s'%id(self)) self.name = name print('bnm.name is %s'%(self.name))print('asd_id is %s'%id(asd))print('bnm_id is %s'%id(bnm))o1 = bnm('ni')print('o1_id is',id(o1))# asd_id is 49838320# bnm_id is 49838768# asd.__new__() is running. cls id is 49838768# r_id is 49848400# bnm.__init__() is running, self id is 49848400# bnm.name is ni# o1_id is 49848400
注意 : bnm 和 cls 是同一个对象! r 和 o1 也是同一个对象 !
应用
仿tornado实现自定义类的初始化方法:
View Code
定义类时,只要继承了asd类,就会将initialize方法作为初始化方法,是不是感觉很(wu)酷(lun)炫(yong)?
0 0
- 一个案例深入Python中的__new__和__init__
- [深入Python]__new__和__init__
- [深入Python]__new__和__init__
- python 中的 __new__ 和 __init__
- Python中的__init__和__new__
- 浅谈 Python 中的 __init__ 和 __new__
- 详解Python中的__init__和__new__
- 详解Python中的__init__和__new__
- Python中的__new__和__init__的区别
- python __new__ 和 __init__
- python __new__和__init__
- Python中__new__() 和 __init__()
- python中__new__和__init__
- python __init__和__new__之间的区别
- python __init__和__new__之间的区别
- python中__new__和__init__的区别
- python __new__()和__init__()哪个更早?
- python之__init__()和__new__()的区分
- Windows 10 & Visual Studio 2015 配置 Caffe
- javascript代码引入【小结】
- 常见的存储过程实例
- 分布式小练习FastDFS, exec 函数复习,log模块集成 gdb调试复习,Makefile
- 网页JavaScript时间出现 117年 请调整您的计算机日期! -------最好的解决办法
- 一个案例深入Python中的__new__和__init__
- 网络编程--客户端返回connect refused 和 no route to host
- Spark SQL 与 Spark SQL on Hive 区别
- Oracle存储过程基本语法介绍
- MySQL存储过程详解 mysql 存储过程
- 内部分享栏
- (转)Android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
- 淡入淡出
- 《算法竞赛入门经典》第七章7.1,7.2,7.3(总结)