本文共 2331 字,大约阅读时间需要 7 分钟。
__new__是生成一个实例、
__init__是初始化一个实例,给实例的属性赋值或者调用实例的方法
__new__在__init__前调用,有了实例才能用__init__方法来操作实例。
顺便看了一下单例,之前刚学Python时候就是知道单例这么个概念,根本不理解,看单例的实现代码也是不知其所以然
如今再看,单例还是挺简单的嘛。。。,就是让类始终只有一个实例,相当于所有实例的内存地址都一样。
而__new__方法刚好可以实现一个单例。
代码如下:
# -*- coding: UTF-8 -*-#非单例的类Aclass A(object): def __init__(self): self.attr='test'a=A()b=A()print(id(a),id(b))print(a is b)#单例类Singleclass Single():# class Single(object): # 下面cls参数我的理解就是类似self,self表示实例本身,那么cls就是代表Single本身 def __new__(cls): # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 #如果Single类没有实例instance if not hasattr(cls, 'instance'): # 调用cls的父类object的__new__方法,返回一个类的实例instance,Python3和Python2的调用方法不一样,明显python3更简单 #python3 cls.instance = super().__new__(cls) #python2 # cls.instance = super(Single, cls).__new__(cls) #这里通过__bases__方法可以看出Single的父类是object,python3默认继承新式类object,所以这么写就行class Single() print('Single父类是:%r'%cls.__bases__) return cls.instance#另一种实现方法""" attr = None def __new__(cls, *args, **kwargs): if not cls.attr: cls.attr=super(Single,cls).__new__(cls,*args, **kwargs) print('Single父类是:%r'%cls.__bases__) return cls.attr"""if __name__ == '__main__': s1=Single() print(s1.__class__) s2=Single() print(id(s1),id(s2)) print(s1 is s2)
输出结果:
31933808 31934032
False Single父类是:<class 'object'> <class '__main__.Single'> Single父类是:<class 'object'> 31935344 31935344 True
可以看出非单例A的两个实例a、b的地址不一样,所以a和b是两个实例
而单例类Single的两个实例s1和s2地址一样,说明s1和s2其实都是__new__里生成的这个cls.instance实例,一个东西。
而在python2环境下,输出结果如下,
(40635976L, 40636088L)
False __main__.Single (40663240L, 40663688L) False
s1,s2地址不同,因为
class Single():这里没继承object,所以没法调用__new__
改成class Single(object)后输出结果就对了:
(39062944L, 39063168L)
False Single父类是:<type 'object'> <class '__main__.Single'> Single父类是:<type 'object'> <__main__.Single object at 0x0000000002540F28> (39063336L, 39063336L) True
但有一点不明白的是python2没继承object的话,就没有调用__new__方法,那么是如何生成实例的的呢?查了一下没差到太多资料,懒得查了。
只看了Stack Overflow这么个简答的回答,用处也不太
0421补充:
# class A(object):class A(): def __init__(self): self.name='wang'print('father of A:',A.__bases__)
Python3下打印结果:
father of A: (<class 'object'>,)
Python2下打印结果:
('father of A:', ())
如果这么定义类:
class A(object):
打印结果如下:
('father of A:', (<type 'object'>,))
转载地址:http://wcxws.baihongyu.com/