python中的__new__方法与__init__方法区别与调用;通过使用__new__实现单例模式

本文只讨论python2环境下的一些必知相关话题,秉承极简阐述

许多pythoner在编程的过程中可能使用过_new__init_方法,但是却没有去理解过它们,今天以前我也一样,但是今天以后我可以说我理解了!

本文所有与类有关的话题中,类都指的是新类

分别有什么功能

__new__是用来创造一个类的实例(constructor),调用时所接收的第一个参数是cls

而__init__是用来初始化一个实例(initializer),调用时所接收的第一个参数是self

调用顺序

先调用new方法然后再调用init方法

原因:既然init是用来初始化一个实例的,那么实例哪里来的呢,当然要先调用new来创建然后才能对这个实例进行初始化。

调用时传参的区别

其实能理解调用顺序的话对于传递的参数就很好理解了:

__new__所接收的第一个参数是cls,因为要创建实例,那么实例是根据什么来创建呢?当然是类了,所以传递cls;

__init__所接收的第一个参数是self,self指的是要初始化的对象,也就是new出来的对象

两者在调用时候的联系

下文将通过重载_new__init_来讲解两者在调用时的不同

注意:

__init__中不能有返回值

这里写图片描述

看下图,我们可以知道一般情况:

在__new__返回一个新创建并且属于该类的实例时当前类的__init__会被调用

这里写图片描述

看下图我们得到另一种情况:

如果__new__返回的实例不属于当前类,那么当前类的__init__不会被调用;另外,如果__new__不返回任何对象的话也会出现这种情况

这里写图片描述

一个小练习

通过使用__new__实现单例模式
单例模式是确保一个类只有一个实例,并且这个实例是自己创造的,在系统中用到的都是这个实例
class SingleTon(object):
    def __new__(cls, *args, **kwargs):
    #每一次实例化的时候,我们都只会返回这同一个instance
        if not hasattr(cls, 'instance'):
            cls.instance = super(SingleTon, cls).__new__(cls)
        return cls.instance

class MyClass(SingleTon):

    def __init__(self, val):
        self.val = val

    def obj_fun(self):
        print self.val, 'obj_fun'

if __name__=="__main__":
    a = MyClass(1)
    b = MyClass(2)
    print a is b
    print id(a), id(b)
    # 类型验证
    print type(a)  # <class '__main__.MyClass'>
    print type(b)  # <class '__main__.MyClass'>

运行结果如下:
这里写图片描述

由以上运行结果中两个实例的id一致可验证实现了单例模式

那么非单例模式会返回什么呢,我们修改MyClass的继承类如下

class MyClass(object):

运行结果如下:

一目了然,我们创建了两个不同的实例,非单例模式

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值