详解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__() - <class '__main__.Demo'> 
__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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值