一、__init__ 方法是什么?

使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候。

这样便是__init__最普通的用法了。

但__init__其实不是实例化一个类的时候第一个被调用 的方法。当使用 Persion(name, age) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 __new__ 方法。

二、__new__ 方法是什么?

__new__方法接受的参数虽然也是和__init__一样,但__init__是在类实例创建之后调用,而 __new__方法正是创建这个类实例的方法。

class Person(object):"""Silly Person"""def __new__(cls, name, age):print('__new__ called.')# return super(Person, cls).__new__(cls, name, age)return super(Person, cls).__new__(cls)def __init__(self, name, age):print('__init__ called.')self.name = nameself.age = agedef __str__(self):return '<Person: %s(%s)>' % (self.name, self.age)if __name__ == '__main__':piglei = Person('piglei', 24)print(piglei)

输出:

 __new__ called.

 __init__ called.

 <Person: piglei(24)>

通过运行这段代码,我们可以看到,__new__方法的调用是发生在__init__之前的。其实当 你实例化一个类的时候,具体的执行逻辑是这样的:

1.p = Person(name, age)
2.首先执行使用name和age参数来执行Person类的__new__方法,这个__new__方法会 返回Person类的一个实例(通常情况下是使用 super(Persion, cls).__new__(cls, … …) 这样的方式),
3.然后利用这个实例来调用类的__init__方法,上一步里面__new__产生的实例也就是 __init__里面的的 self
所以,__init__ 和 __new__ 最主要的区别在于:
1.__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
2.__new__ 通常用于控制生成一个新实例的过程。它是类级别的方法。
但是说了这么多,__new__最通常的用法是什么呢,我们什么时候需要__new__?

三、__new__ 的作用

依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。
首先我们来看一下第一个功能,具体我们可以用int来作为一个例子:
假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码。

但运行后会发现,结果根本不是我们想的那样,我们任然得到了-3。这是因为对于int这种 不可变的对象,我们只有重载它的__new__方法才能起到自定义的作用。
这是修改后的代码:

class PositiveInteger(int):def __new__(cls, value):return super(PositiveInteger, cls).__new__(cls, abs(value))i = PositiveInteger(-3)
print(i)

输出:

通过重载__new__方法,我们实现了需要的功能。
另外一个作用,关于自定义metaclass。准备在专门写一下python中的metaclass和__new__的关系

四、用__new__来实现单例

事实上,当我们理解了__new__方法后,我们还可以利用它来做一些其他有趣的事情,比如实现 设计模式中的 单例模式(singleton) 。
因为类每一次实例化后产生的过程都是通过__new__来控制的,所以通过重载__new__方法,我们 可以很简单的实现单例模式。

class Singleton(object):def __new__(cls):# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象if not hasattr(cls, 'instance'):cls.instance = super(Singleton, cls).__new__(cls)return cls.instanceobj1 = Singleton()
obj2 = Singleton()obj1.attr1 = 'value1'
print(obj1.attr1, obj2.attr1)
print(obj1 is obj2)

输出:

value1 value1
True

补充:

_init__函数并不是真正意义上的构造函数,__init__方法做的事情是在对象创建好之后初始化变量。真正创建实例的是__new__方法。

参考:

(1)、http://python.jobbole.com/86506/

(2)、https://juejin.im/post/5add4446f265da0b8d4186af

python中的__new__和__init__相关推荐

  1. python中的__new__与__init__,新式类和经典类(2.x)

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

  2. python中__init__后面加特殊符号_详解Python中的__new__、__init__、__call__三个特殊方法...

    __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪来的self) __init__ : 对象的初始化, 是一个实例方法,第一个参数是sel ...

  3. Python中:self和__init__的含义 + 为何要有self和__init__

    为什么80%的码农都做不了架构师?>>>    本文转自: http://www.crifan.com/summary_the_meaning_of_self_and___init_ ...

  4. python init self_转载--------Python中:self和__init__的含义 + 为何要有self和__init__

    背景 Python中的self,__init__的含义是啥?为何要有self,__init这些东西? 解释之前,先说几句 1.到目前为止,我虽然也已写了不算很少的python的代码,但是,还真的没有太 ...

  5. python中_new_和_init_的区别_Python 中的__new__和__init__的区别

    [同] 二者均是Python面向对象语言中的函数,__new__比较少用,__init__则用的比较多. [异] __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是 ...

  6. Python中的__new__()方法的使用

    __new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object:   @staticmethod # known cas ...

  7. python中的__new__概念(工厂

    __new__方法实际上在__init__方法之前执行,用于创建类的实例.然而__init__方法负责实例创建后对其进行自定义,__new__方法才是实际上创建并返回实例的方法. __new__方法的 ...

  8. Python中的__new__(new函数)

    1.魔术方法 :  系统的函数,函数名称为 __xxx__,如 __init__,__new__,__del__等 __init__ : 可以定义一个对象的初始化操作,但是,__init__ 并不是第 ...

  9. python new方法_Python中的__new__()方法的使用

    __new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object: @staticmethod # known case ...

最新文章

  1. 学习 JavaScript (四)核心概念:操作符
  2. 连登GitHub TOP榜,中国开发者在行动!
  3. 浅谈CSS重构样式表性能
  4. 试试Linux下的ip命令,ifconfig已经过时了
  5. fc oracle,使用 CLI 配置 FC
  6. Struts标签和OGNL表达式
  7. 判断对象是否为数组/函数
  8. 课节5:图神经网络算法(二):GraphSage实践
  9. PAT甲级1024 ASCII码与整数转换
  10. 乐观锁 与 悲观锁 来解决数据库并发问题
  11. 第三百七十二天 how can I 坚持
  12. Qt中的对话框(模态,非模态,关于,问题,文件)
  13. 计算机 大文件查找,win7笔记本电脑如何快速查找大文件
  14. UVM学习整理——附录(部分组件源码)
  15. h5如何实现贪吃蛇小游戏
  16. ax的范数最大_各类范数定义
  17. 人工智能正在重塑生产方式、优化产业结构、提升生产效率、赋能千行百业
  18. 中国的教育缺少什么?
  19. Linux---man的使用
  20. 1小时会议录音,30秒整理成文字,这款APP有点牛呀!

热门文章

  1. JAVA项目怎么不是蓝色_解决IDEA创建maven项目时pom.xml没有变蓝的问题
  2. centos7网卡编辑_CentOS7修改网卡为eth0
  3. 1 计算机主机里面都有些什么东西,计算机主机和外设分别包括那些东西?
  4. Invalid argument: Key: label. Data types don't match. Data type: int64 but expected type: float
  5. windows系统查找文件-通配符的使用
  6. Java的JDBC事务详解
  7. 类的特殊成员反射异常处理
  8. 在linux上安装jdk(转载)
  9. linux(fedora) 下dvwa 建筑环境
  10. Ios17个常用代码整理