__new__()
是新式类中新出现的类方法,它在构造方法(__init__()
)之前调用。
__new__()
的声明
def __new__(cls, *args, **kwargs):
pass
__new__()
的参数和__init__()
一样,但__init__()
是在类实例创建之后调用,而 __new__()
方法正是创建类实例的方法。__init__()
有一个参数self,self就是__new__()
返回的实例,__init__()
在__new__()
的基础上完成一些其它初始化的动作,__init__()
不需要返回值。
class Foo(object):
def __init__(self):
print '__init__'
def __new__(cls,*args,**kargs):
print '__new__'
return super(Foo,cls).__new__(cls,*args,**kargs)
f = Foo()
'''
__new__
__init__
'''
上述代码可证明__new__()
方法的调用在__init__()
之前。
执行过程如下
- f = Foo()
- 执行Foo的
__new__()
方法,__new__()
方法返回Foo的一个实例 - 执行
__new__()
方法返回实例的__init__()
方法
由以上可知,__init__()
和__new__()
的区别主要有以下
__init__()
通常用于初始化一个新实例,控制实例的初始化过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后,它是实例级别的方法__new__()
通常用于控制生成一个新实例,它是类级别的方法
以建房子做比喻,
__new__()
方法负责开发地皮,打下地基,并将原料存放在工地;
__init__()
方法负责从工地取材料建造出地皮开发招标书中规定的大楼;大楼的细节设计,装修交给客户完成(也就是实例的使用者)。
可利用__new__()
实现单例模式
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Singleton(object):
'''单例模式'''
def __init__(self):
print '__init__'
def __new__(cls,*args,**kargs):
if not cls.__dict__.get('_Singleton__instance'):
cls._Singleton__instance = super(Singleton,cls).__new__(cls,*args,**kargs)
return cls._Singleton__instance
m = Singleton()
n = Singleton()
print m is n
'''
__init__
__init__
True
'''
__new__()
的特性
__new__()
方法在类准备将自身实例化时调用;__new__()
方法始终都是类的静态方法,即使没有被加上静态方法装饰器;
注意
如果在定义新式类时没有重定义
__new__()
,Python默认按照MRO顺序调用其父类的__new__()
方法来构造该类的实例,因为object是所有新式类的基类,所以一定能找到__new__()
方法;如果新式类重写了
__new__()
方法,那么可以任意选择一个新式类的__new__()
方法来制造实例;(一定要是新式类,新式类必有
__new__()
,因为所有新式类都是object的后代,而经典类则没有__new__()
方法)如果
__new__()
没有返回当前类的实例,那么当前类的__init__()
方法是不会被调用的;如果
__new__()
返回其他类(新式类或经典类均可)的实例,那么会调用被返回的那个类的构造方法;也就是说返回谁的实例,就调用谁的
__init__()
方法,不返回实例,不会调用__init__()
方法class Foo1(object): def __init__(self, *args, **kwargs): print "Foo1 __init__" def __new__(cls, *args, **kwargs): return super(Foo1,cls).__new__(cls, *args, **kwargs) class Foo2(object): def __init__(self): print "Foo2 __init__" def __new__(cls, *args, **kwargs): '''返回Foo1的实例''' return Foo1() class Foo3(object): def __init__(self): print "Foo3 __init__" def __new__(cls, *args, **kwargs): pass foo1 = Foo1() #Foo1 __init__ print type(foo1) #<class '__main__.Foo1'> foo2 = Foo2() #Foo1 __init__,调用的是Foo1的__init__()方法 print type(foo2) #<class '__main__.Foo1'> foo3 = Foo3() print type(foo3) #<type 'NoneType'>
转载请标明出处,原文地址(http://blog.csdn.net/lis_12/article/details/54631089).
如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。
参考网址