python 关于 __new__ , __init__ , cls, self 的碎碎念。

本文旨在澄清 python 里 __new__ vs __init__cls vs self 的概念。 python

不少初学者会困扰,python的“魔法函数” __new__ 有啥用? 跟__init__有啥区别? 为何有的函数第一个输入变量是self, 有的倒是cls? 这有啥区别?函数

好,废话很少说,先看一个例子:code

class A(object):
    def __new__(cls):
        print("A.__new__ called")
        return super(A, cls).__new__(cls)

    def __init__(self):
        print("A.__init__ called")

A()
print('finished')

运行结果为:orm

A.__new__ called
A.__init__ called
finished

为何结果是这样呢?
由于:__new__ 负责建立一个 object;以后 __init__ 负责初始化这个 object。it

有点绕是吧,再说具体点:io

A()被 call 的时候,__new__ 就自动执行了, 它建立了一个object(class的具体实例)并返回这个object,而后__init__接手这个实例再接着执行。 form

每当__new__ 建立并返回一个实例时,__init__ 就接手这个实例而后执行,这个实例就是__init__ 的第一个输入变量,永远不变的, 默认的self。 说到这里,self怎么来的应该很清楚了吧。class

在日常应用中,咱们定义某个class时几乎不会去写它的__new__方法,因而当咱们call这个class时,python会一直往上追溯到有__new__的父辈class, 一般咱们自定义的class都是object的子类,因此执行的都是它的__new__
object__new__建立并返回的这个实例,是裸的。 而后咱们的class__init__再接手这个裸的实例去进一步加工,好比加上各类 self.xxx = xxx, 或再执行一些别的code, 这个过程就是initialization。注意它和creation的区别,应该说的很清晰了吧。变量

那假如咱们本身定义一个坏了的__new__, 它没有返回一个实例,这事会发生什么呢?好比:object

class A(object):
    def __new__(cls):
        print("A.__new__ called")
        #return super(A, cls).__new__(cls)

    def __init__(self):
        print("A.__init__ called")

A()

运行一下,发现结果是:

A.__new__ called
finished

哈哈固然啦,__new__没有返回一个建立好的实例,那么__init__天然就执行不了了。 上头没有提供食材,厨子就揭不开锅作饭嘛。

这个时候有人会问了,为啥 __init__() 里面是 self, 而__new__()里面是cls呢?

首先,咱们澄清一下概念:

一、self表示一个具体的实例(instance)自己。(若是用了@staticmethod,那么就能够无视这个self,由于staticmethod就能够理解成一个普通的函数)

二、cls表示这个类(class)自己。

OK, __init__() 里面的self已经说清楚了,是刚刚__new__出炉的一个建立好的实例(object / instance); 那__new__()里面是cls又是指哪一个class呢?

简单说来:哪一个class召唤了__new__, cls就默认是哪一个class

再看一个例子 (Singleton 单例模式的实现):

class Singleton(object):

    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)

            print('\n')
            print('cls is ', cls)
            print(type(cls._instance),  cls._instance)

        else:
            print(' {}  already exists'.format(cls._instance))
        return cls._instance


class Bus(Singleton):
    def sendData(self,data):
        pass


class BusSon(Bus):
    def sendData(self,data):
        pass


if __name__ == '__main__':

    busson1 = BusSon()
    bus1 = Bus()
    print('------------------------\n')

    busson2 = BusSon()
    bus2 = Bus()

    print('------------------------\n')


    Bus.__new__(BusSon)
    Bus()
    x = Singleton.__new__(Bus)
    print(x)
相关文章
相关标签/搜索