__init__和__new__

一、__new__和__init__

曾经我幼稚的以为认识了python的__init__()方法就相当于认识了类构造器,结果,__new__()方法突然出现在我眼前,让我突然认识到原来__new__才是老大。为什么这么说呢?

我们首先得从__new__(cls[,...])的参数说说起,__new__方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给__init__方法初始化,这一下子就看出了谁是老子谁是小子的关系。

所以,__new__方法(第一个执行)先于__init__方法执行:

class A:
pass class B(A):
def __new__(cls):
print("__new__方法被执行")
return super().__new__(cls) def __init__(self):
print("__init__方法被执行") b = B()
__new__方法被执行
__init__方法被执行

我们比较两个方法的参数,可以发现__new__方法是传入类(cls),而__init__方法传入类的实例化对象(self),而有意思的是,__new__方法返回的值就是一个实例化对象(ps:如果__new__方法返回None,则__init__方法不会被执行,并且返回值只能调用父类中的__new__方法,而不能调用毫无关系的类的__new__方法)。我们可以这么理解它们之间的关系,__new__是开辟疆域的大将军,而__init__是在这片疆域上辛勤劳作的小老百姓,只有__new__执行完后,开辟好疆域后,__init__才能工作。

绝大多数情况下,我们都不需要自己重写__new__方法,但在当继承一个不可变的类型(例如str类,int类等)时,它的特性就尤显重要了。我们举下面这个例子:

class CapStr(str):
def __init__(self, string):
string = string.upper() a = CapStr("I love China!")
print(a)

I love China!

class CapStr(str):
def __new__(cls, string):
string = string.upper()
return super().__new__(cls, string) a = CapStr("I love China!")
print(a)

I LOVE CHINA!

我们可以根据上面的理论可以这样分析,我们知道字符串是不可改变的,所以第一个例子中,传入的字符串相当于已经被打下的疆域,而这块疆域除了将军其他谁也无法改变,__init__只能在这块领地上干瞪眼,此时这块疆域就是”I love China!“。而第二个例子中,__new__大将军重新去开辟了一块疆域,所以疆域上的内容也发生了变化,此时这块疆域变成了”I LOVE CHINA!“。

二、总结

  • __new__和__init__想配合才是python中真正的类构造器。

  • 先执行__new__在执行__init__

最新文章

  1. XUnit - Shared Context between Tests
  2. 最好用的JQuery插件集合以及组合拳
  3. jQuery 利用 parent() parents() 寻找父级 或祖宗元素
  4. oracle kill session
  5. JAVA Day5
  6. OpenERP在哪储存附件?
  7. [ActionScript 3.0] 喷泉效果
  8. IOS第六天(3:scrollView 图片轮播器)
  9. [转] Web 前端优化最佳实践之 Mobile(iPhone) 篇
  10. 问题集-- SQL 约束名不能重复
  11. .NET架构师技能体系
  12. 详解Android ActionBar之二:ActionBar添加Tabs标签和下拉导航
  13. Android传感器的使用(GravieySensor)
  14. webpack之基础学习
  15. lhgDialog
  16. Intent用法
  17. python函数式编程之迭代器
  18. Angular 学习笔记 ( CDK - Accessibility )
  19. [leetcode]70. Climbing Stairs爬楼梯
  20. Win10更新搜狗输入法后重启输入密码蓝屏

热门文章

  1. 大数据之虚拟机配置和环境准备及hadoop集群搭建
  2. 使用BP拦截POST型请求包 (9.20 第九天)
  3. Python的递归深度问题
  4. 高分Essay写作需注意以下几个细节
  5. Mysql修改默认提示符
  6. PAT 2014 秋
  7. 开始linux课程预习工作
  8. POJ 1651:Multiplication Puzzle 矩阵相乘式DP
  9. 学习Github必须要会的知识
  10. 阿里云云服务器测试uwgis的基本流程