为什么是
我只是想简化我的一个类,并且以轻量级设计模式的相同风格引入了一些功能。
不过,我有点困惑,为什么__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