• python __new__ __init__


    写过python类的都会知道__init__,可能也了解__new__。我之前也了解__new__,但只做的它发生在__init__之前。其他的就比较模糊了

    今天在学习单例模式时,看到有人用__new__去实例化,也有人用__init__去初始化,甚为奇怪,就查了一下别人的文章,总结一下。

    简单来说,就是__new__负责返回一个实例,__init__负责初始化返回的那个实例,就是给返回的实例加上一些属性。__init__方法必须覆写,而__new__方法一般在__init__之前自动执行。如果__new__不能正确返回对象,__init__就不会调用,除非我们自己覆写了__new__,没有正确返回实例,否则不会出现这种情况。

    例子来一发

    
    
    class Human(object):                                                  
          def __init__(self,n,a):                                    
               print "__init__ called"                                    
               self.name = n                                           
               self.age = a                                             
          def __new__(cls, name,age):                                     
               print "__new__ called"                                     
               return super(Human,cls).__new__(cls,name,age)              
          def tell(self):                                                 
               print  "My nama is %s,my age is %d"%(self.name,self.age)   
    
    
    h = Human("lll",11)  
    
    输出:
    _new__ called
    __init__ called
    
    
    

    这个就是我们经常用到的__init__,从输出结果显而易见,__new__先调用,__init__后调用。当我们去实例化一个对象时,基本过程是:

    1.h = Human("lll",11)

    2.有了第一步后,python解释器会立马去调用__new__,这个方法会返回一个Human的实例,并且给这个实例绑定了属性,这里就是name和age两个属性。方法的调用一般就是super(Human,cls).__new__(cls,name,age)这种格式。

    3.__init__会接收到__new__返回的实例对象,和已经绑定的属性,然后给这些属性赋值,就是self.name = n ,self.age = a,给name属性赋值传递进来的n,age属性赋值传递进来的a。到此一个对象就建立完毕,可以用这个对象去调用其他方法了

    所以__init__主要是用于初始化对象,给属性赋值,或者做一些比如print的事情,属于实例级别的方法__init__没有返回,__new__是生产一个实例,属于类级别的方法。__new__有返回值,返回新的对象。

    刚才的__new__我们平时是不会去写出来的,属于自动调用。但是,有时候我们并不想让它去自动调用,就必须覆写它。

    比如,如果我们的类继承自int,str,tuple这些类时,这些类是不可变的,所以在产生实例时他就是不可变的,但是我们继承了不可变的类又想让它可变,就只能去覆写它的__new__

    比如我想判断一个数字是不是正数,就要继承int(可以保证是一个数字),然后在初始化中去判断,不是专门写一个函数去判断。

    class ifPositive(int):
    	def __init__(self,value):
    		super(ifPositive,self).__init__(self,True if value>0 else False)
    
    i = ifPositive(3)
    返回的是3,不是我们期待的1(此处不是返回True,是1,如果不是正数则返回0)
    

     下面通过覆写__new__方法实现功能

    class ifPositive(int):
    	def __new__(cls,value):      这里的第一个参数默认是cls
    		return super(ifPositive,cls).__new__(cls,True if value>0 else False)    此处一定要加return
    
    i = ifPositive(2)
    返回1
    i = ifPositive(-1)
    返回0
    

     查这两个方法时也看到__call__,此处也补充一下

    一个类实现了这个函数,那么它的实例就多了一个功能,可以当作函数来用,直接在对象后面加上括号,里面就是__call__的参数,就会返回__call__方法的结果。还就拿上面的Human类,比如我给那个Human类加了一个方法

    def __call__(self,attr):
        if attr == "name":  
            return self.name
        else:               
            return self.age 
    
    h = Human("lll",11) 
    print h("name")     
    会返回“lll"
    
  • 相关阅读:
    原生js系列 删除元素
    事件绑定的几种方式
    js的五种输出方式
    三、浏览器事件处理机制--事件循环(event loop)
    二、事件流、事件代理
    一、事件的分类
    js数据类型转换
    html锚点
    观察者模式
    策略模式
  • 原文地址:https://www.cnblogs.com/buptldf/p/4985030.html
Copyright © 2020-2023  润新知