为什么是

我只是想简化我的一个类,并且以轻量级设计模式的相同风格引入了一些功能。

不过,我有点困惑,为什么__init__总是在__new__之后__new__ 。 我并不期待这一点。 任何人都可以告诉我为什么会发生这种情况,以及我如何才能实现此功能? (除了把这个实现放到__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

为什么?


当你需要控制新实例的创建时使用__new__ 。 当需要控制新实例的初始化时,使用__init__

__new__是实例创建的第一步。 它首先被调用,并负责返回你的类的新实例。 相反, __init__不返回任何内容; 它只负责在实例创建后对其进行初始化。

一般来说,除非你继承了像str,int,unicode或tuple这样的不可变类型,否则你不需要重载__new__

来自:http://mail.python.org/pipermail/tutor/2008-April/061426.html

你应该考虑你想要做的事情通常是通过工厂来完成的,而这是实现它的最好方式。 使用__new__不是一个很好的清理解决方案,所以请考虑工厂的使用情况。 在这里你有一个很好的工厂例子。


__new__是静态类方法,而__init__是实例方法。 __new__必须首先创建实例,所以__init__可以初始化它。 请注意, __init__self作为参数。 在你创建实例之前,没有self

现在,我收集,你正在尝试在Python中实现单例模式。 有几种方法可以做到这一点。

另外,从Python 2.6开始,您可以使用类装饰器。

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class 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来将任何其他正常的类变成单__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

然而,这可能比这种情况下真正需要的更深的魔力!

链接地址: http://www.djcxy.com/p/82185.html

上一篇: Why is

下一篇: What is the C# equivalent of friend?