【发布时间】:2015-09-17 23:18:31
【问题描述】:
我正在尝试为我的一组不可变类创建一个 memoziation 系统来处理符号表达式。我到目前为止所得到的如下。我不喜欢的是我不能直接阻止对__init__ 的调用,并且必须在对象中填充一些东西(new_inst 属性)来跟踪__init__ 方法是否应该做任何事情.有没有更 Pythonic 的方式来做到这一点?
(new_inst 参数只是我告诉__new__ 是否“停止”对__init__ 的调用的一种简单方法。实际上,这将基于对象是否存在于对象缓存中已经并且不会成为__new__ 或__init__ 的参数)。
my_cache = {}
class Base(object):
def __new__(cls, *args, **kwargs):
signature = (cls, args)
if signature in my_cache:
self = my_cache[signature]
self.new_inst = True
else:
self = object.__new__(cls, *args, **kwargs)
my_cache[signature] = self
self.new_inst = False
return self
class A(Base):
def __init__(self, a):
if not self.new_inst:
print "Initializing A object with a=%d"%(a,)
self.a = a
class B(Base):
def __init__(self, a, b):
if not self.new_inst:
print "Initializing B object with a=%d, b=%d"%(a,b)
self.a = a
self.b = b
a1 = A(1)
a2 = A(1)
a3 = A(3)
b1 = B(1, 2)
b2 = B(1, 2)
b3 = B(1, 3)
print id(a1), id(a2), id(a3)
print id(b1), id(b2), id(b3)
输出:
Initializing A object with a=1
Initializing A object with a=3
Initializing B object with a=1, b=2
Initializing B object with a=1, b=3
140246850102904 140246850102904 140246850102960
140246850103016 140246850103016 140246850103072
编辑:显然我不清楚我在说什么,所以这里有一个更具体的例子。如您所见,第二个 A(1) 不会导致第二次初始化,它返回相同的 id。
【问题讨论】:
-
我认为你的第一个 if 语句简化为 self.new_inst = (new_inst is not None)
-
@Prune 就像我在 P.S. 中提到的那样,它看起来很傻,但这是因为它代表了将存在的更复杂的 if 语句。在 if 下我会放置
object.__new__位,在 else 下我会从其他地方检索对象。 -
所以你正在实现单例模式,其中有问题的对象的
__new__方法也用作工厂模式? -
基本上,除了我似乎看到“单例模式”的每个地方之外,它指的是将一个类重新绑定到一个实例,这不是我想要的。看来我想要的最好用我没有真正看过的元类来完成(一旦有机会就会看)。
标签: python immutability memoization