我只是想精简我的一个类,并引入了一些与flyweight design pattern风格相同的功能。
但是,我有点困惑,为什么__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
为什么?
__new__
是静态类方法,而__init__
是实例方法。__new__
必须先创建实例,因此__init__
可以对其进行初始化。请注意,__init__
将self
作为参数。在您创建实例之前,没有self
。现在,我认为,您正在尝试用Python实现singleton pattern。有几种方法可以做到这一点。
另外,从Python 2.6开始,您可以使用类decorators。
在大多数著名的OO语言中,像
SomeClass(arg1, arg2)
这样的表达式将分配一个新实例,初始化实例的属性,然后返回它。在大多数著名的OO语言中,“初始化实例的属性”部分可以通过定义一个构造函数为每个类定制,这个构造函数基本上只是一个代码块,它对新实例(使用提供给构造函数表达式的参数)进行操作,以设置所需的任何初始条件。在Python中,这对应于类
__init__
方法。Python的
__new__
只不过是“allocateanewinstance”部分的每个类的类似定制。这当然允许您做一些不寻常的事情,比如返回一个现有的实例,而不是分配一个新的实例。所以在Python中,我们不应该认为这部分必然涉及到分配;我们所需要的只是__new__
从某个地方找到一个合适的实例。但它仍然只是作业的一半,而且Python系统不可能知道,有时您想在之后运行作业的另一半(
__init__
),有时您不想这样做。如果您想这样做,您必须明确地说。通常,您可以重构以便只需要
__new__
,或者不需要__new__
,或者__init__
在已初始化的对象上的行为不同。但如果您真的想这样做,Python实际上允许您重新定义“作业”,这样SomeClass(arg1, arg2)
就不必调用__new__
后面跟着__init__
。为此,您需要创建一个元类,并定义它的__call__
方法。元类只是类的类。类‘
__call__
方法控制调用类实例时发生的事情。因此,一个元类'__call__
方法控制调用类时发生的事情;也就是说,它允许您从头到尾重新定义实例创建机制。这是最优雅地实现完全非标准实例创建过程(如singleton模式)的级别。事实上,只要不到10行代码,您就可以实现一个Singleton
元类,它甚至根本不需要您使用__new__
,只需添加__metaclass__ = Singleton
,就可以将任何或者普通类变成一个单一类!然而,这可能是更深的魔术比真正的理由,为这种情况!
从2008年4月起,在mail.python.org上发布When to use ^{} vs. ^{}? 。
你应该考虑到你要做的通常是用Factory完成的,这是最好的方法。使用
__new__
不是一个好的清洁解决方案,因此请考虑使用工厂。这是a good factory example。相关问题 更多 >
编程相关推荐