为什么_init_()总是在_new_()之后调用?

为什么_init_()总是在_new_()之后调用?

我只是试图精简我的一个类,并引入了一些与飞重设计模式.

但是,我有点搞不懂为什么__init__总是在后面调用__new__..我没想到会这样。有人能告诉我为什么会发生这种情况吗?否则我如何实现这个功能?(除了将实现放入__new__这感觉很烦人。)

下面是一个例子:

class A(object):
    _dict = dict()

    def __new__(cls):
        if 'key' in A._dict:
            print "EXISTS"
            return A._dict['key']
        else:
            print "NEW"
            return super(A, cls).__new__(cls)

    def __init__(self):
        print "INIT"
        A._dict['key'] = self        print ""a1 = A()a2 = A()a3 = A()

产出:

NEW
INIT

EXISTS
INIT

EXISTS
INIT

为什么?


心有法竹
浏览 551回答 3
3回答

精慕HU

__new__是静态类方法,而__init__是实例方法。__new__必须首先创建实例,因此__init__可以初始化它。请注意__init__取走self作为参数。在创建实例之前,没有self.现在,我想,你在努力实现单例模式在Python里。有几种方法可以做到这一点。此外,与Python2.6一样,您也可以使用类装饰师.def singleton(cls):     instances = {}     def getinstance():         if cls not in instances:             instances[cls] = cls()         return instances[cls]     return getinstance@singletonclass MyClass:   ...

红颜莎娜

在大多数著名的OO语言中,类似于SomeClass(arg1, arg2)将分配一个新实例,初始化实例的属性,然后返回它。在大多数著名的OO语言中,“初始化实例的属性”部分可以通过定义构造器,它基本上只是一个代码块,在新实例上操作(使用提供给构造函数表达式的参数)来设置所需的初始条件。在Python中,这对应于类‘__init__方法。Python的__new__是“分配一个新实例”部分的类似的每类自定义。当然,这允许您执行一些不寻常的事情,比如返回一个现有实例,而不是分配一个新实例。因此,在Python中,我们不应该真的认为这部分涉及到分配;我们所需要的只是__new__想出一个合适的例子。但是它仍然只是工作的一半,Python系统不可能知道有时候您想要运行另一半的作业(__init__事后,有时你不知道。如果你想要那样的行为,你必须明确地说出来。通常,你可以重构,所以你只需要__new__或者说你不需要__new__,或者说是这样__init__在已经初始化的对象上的行为不同。但是如果你真的愿意的话,Python实际上允许你重新定义“任务”,这样SomeClass(arg1, arg2)不一定会打电话__new__紧随其后__init__..为此,您需要创建一个元类,并定义其__call__方法。元类只是类的类。还有一门课__call__方法控制调用类实例时发生的情况。所以元类' __call__方法控制调用类时发生的情况;也就是说,它允许您从头到尾重新定义实例创建机制。..这是您可以最优雅地实现一个完全非标准的实例创建过程的级别,例如单例模式。实际上,使用少于10行代码,您可以实现Singleton元类甚至不需要你__new__ 完全没有,并且可以转动任何否则,将普通类简单地添加到单例类中。__metaclass__ = Singleton!class Singleton(type):     def __init__(self, *args, **kwargs):         super(Singleton, self).__init__(*args, **kwargs)         self.__instance = None     def __call__(self, *args, **kwargs):         if self.__instance is None:             self.__instance = super(Singleton, self).__call__(*args, **kwargs)         return self.__instance然而,这可能是更深的魔法,这是真正需要为这种情况!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python