平台:win8 python2.7
1.__new__
先看下object类中对__new__()方法的定义:
@staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
""" T.__new__(S, ...) -> a new object with type S, a subtype of T """
pass
object将__new__()方法定义为静态方法,并且至少需要
__new__() - <class '__main__.Demo'>
__init__() called...
传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供。(注意:cls表示的是需要实例化的类,de = Demo(),即Demo)
__new__方法实例:
class Demo(object):
def __init__(self):
print '__init__() called...'
def __new__(cls, *args, **kwargs):
print '__new__() - {cls}'.format(cls=cls)
return object.__new__(cls, *args, **kwargs)
if __name__ == '__main__':
de = Demo()
输出:
__new__() - <class '__main__.Demo'>
__init__() called...
在初始化的时候,__new__()方法在__init__()之前先行调用。
__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object的__new__()出来的实例返回。(object.__new__(cls, *args, **kwargs) 或 fatherclass.__new__(cls, *args, **kwargs) 或 super(currentclass, cls).__new__(cls[, ...]))
__init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()在__new__()的基础上可以完成一些其它初始化的动作,__init__()不需要返回值。
>>> class Demo(object):
def __init__(self,a,b):
print self.a
print self.b
def __new__(cls,a,b):
print 'new' + a
print 'new' + b
return object.__new__(cls,a,b)
结果:
>>> a = Demo('2','3')
new2
new3
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
a = Demo('2','3')
File "<pyshell#38>", line 3, in __init__
print self.a
AttributeError: 'Demo' object has no attribute 'a' #报错:demo没有a这个属性
即表明:self.a 初始化给Demo增加属性a
修改后的代码
>>> class Demo(object):
def __init__(self,a,b):
self.a = a
self.b = b
def __new__(cls,a,b):
print 'new' + a
print 'new' + b
return object.__new__(cls,a,b)
>>> a = Demo('1','2')
new1
new2
>>> a.a
'1'
>>> a.__dict__
{'a': '1', 'b': '2'}
我们可以将类比作制造商,__new__()方法就是前期的原材料购买环节,__init__()方法就是在有原材料的基础上,加工,初始化商品环节。
文档里其实有写,如果
__new__ 返回的不是这个类的实例,那么它的 __init__ 方法是不会被调用的。
python脚本之家上的例子,我觉得是错误的,因为没有返回类的实例?!
还有一个单例模式的,通过重载__new__实现的。
class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
判断有没有实例,没有的话,用继承来的__new__返回一个实例。