您的位置:首页 > 编程语言 > Python开发

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

2018-03-11 10:48 951 查看
本文只讨论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):


运行结果如下:

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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐