【问题标题】:Immutable object memoziation pattern in pythonpython中的不可变对象记忆模式
【发布时间】: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


【解决方案1】:

这是 Base 的较短版本。

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。我还没有看到一种更简洁的方法来检测新实例并在分配后对其进行设置。

【讨论】:

  • 我完全不关心__new__ 方法的清洁度。我正在寻找的是一种消除 __init__ 方法中的 if 语句的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 2012-08-31
  • 2019-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
相关资源
最近更新 更多