python中的不可变对象memoziation模式

时间:2015-09-17 23:18:32

标签: python immutability memoization

我正在尝试为我的一组不可变类创建一个memoziation系统来处理符号表达式。到目前为止我得到的是下面的内容。我不喜欢的是,我不能直接阻止对__init__的调用,并且必须在对象(new_inst属性)中填充内容以跟踪{{1}方法应该做任何事情。有更多的pythonic方式吗?

__init__参数只是一种简单的方式让我告诉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)

编辑:显然我不清楚我得到了什么,所以这是一个更具体的例子。如您所见,第二个A(1)不会导致第二次初始化,并返回相同的ID。

1 个答案:

答案 0 :(得分:-1)

这是Base的较短版本。 new

def __new__(cls, *args, **kwargs):
    signature = (cls, args)
    new_inst = signature in my_cache
    self = my_cache.get(signature, object.__new__(cls, *args, **kwargs))
    self.new_inst = new_inst
    return self

这不会节省很多处理时间,但它更干净,更Pythonic。我还没有看到更简洁的方法来检测新实例并在分配后设置它。