详解python中的__new__方法

python中的__new__方法的使用

一丶object类中对__new__方法的定义
class object: 
 @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__()方法定义为静态方法,并且至少需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供。
继承自object的新式类才有__new__
在任何新式类的__new__()方法,不能调用自身的__new__()来制造实例,因为这会造成死循环,如果当前类中没有重写__new__方法,那么就追溯到父类,一直到 object基类
使用object或者没有血缘关系的新式类的__new__()是安全的,但是如果是在有继承关系的两个类之间,应避免互调造成死循环 (子类调用父类,父类调用子类)

二丶我们来看下面类中对__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__() -  
__init__() called... 
发现实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法
__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object的__new__()出来的实例返回。
__init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()在__new__()的基础上可以完成一些其它初始化的动作,__init__()不需要返回值。
若__new__()没有正确返回当前类cls的实例,那__init__()将不会被调用,即使是父类的实例也不行。
我们可以将类比作制造商,__new__()方法就是前期的原材料购买环节,__init__()方法就是在有原材料的基础上,加工,初始化商品环节。

三丶实际应用过程中,我们可以这么使用:
class LxmlDocument(object_ref): 
 cache = weakref.WeakKeyDictionary() 
 __slots__ = ['__weakref__'] 
 def __new__(cls, response, parser=etree.HTMLParser): 
cache = cls.cache.setdefault(response, {}) 
if parser not in cache: 
 obj = object_ref.__new__(cls) 
 cache[parser] = _factory(response, parser) 
return cache[parser] 


该类中的__new__()方法的使用,就是再进行初始化之前,检查缓存中是否存在该对象,如果存在则将缓存存放对象直接返回,
如果不存在,则将对象放至缓存中,供下次使用。 


补充丶 __call__
对象通过提供__call__(slef, [,*args [,**kwargs]])方法可以模拟函数的行为,如果一个对象x提供了该方法,就可以像函数一样使用它,也就是说x(arg1, arg2...)
等同于调用x.__call__(self, arg1, arg2) 。模拟函数的对象可以用于创建防函数(functor) 或代理(proxy).
class Foo(object): 
 def __call__(self): 
pass
 
f = Foo()#类Foo可call 
f()#对象f可call
__init__
__init__ 方法通常用在初始化一个类实例的时候。在调用该初始化方法之前,需要调用一下__new__方法来实例化一个对象并返回,返回的内容即初始化方法中的第一个参数self

你可能感兴趣的:(python,__new__,__call__,__init__,python基础)