为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

心有法竹 2019-06-06 13:36:19
为什么_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为什么?
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

__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:
  ...


查看完整回答
反对 回复 2019-06-06
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

在大多数著名的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

然而,这可能是更深的魔法,这是真正需要为这种情况!


查看完整回答
反对 回复 2019-06-06
  • 3 回答
  • 0 关注
  • 550 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信