我正在解决一个问题,其中我正在实例化许多对象。大多数情况下,实例化的对象是相同的。为了减少内存开销,我希望所有相同的对象指向相同的地址。然而,当我修改对象时,我希望创建一个新的实例--基本上是写时复制行为。在Python中,最好的方法是什么?
享元模式接近于这个问题。下面是一个示例(来自http://codesnipers.com/?q=python-flyweights):
import weakref
class Card(object):
_CardPool = weakref.WeakValueDictionary()
def __new__(cls, value, suit):
obj = Card._CardPool.get(value + suit, None)
if not obj:
obj = object.__new__(cls)
Card._CardPool[value + suit] = obj
obj.value, obj.suit = value, suit
return obj
这个的行为如下所示:
>>> c1 = Card('10', 'd')
>>> c2 = Card('10', 'd')
>>> id(c1) == id(c2)
True
>>> c2.suit = 's'
>>> c1.suit
's'
>>> id(c1) == id(c2)
True
期望的行为应该是:
>>> c1 = Card('10', 'd')
>>> c2 = Card('10', 'd')
>>> id(c1) == id(c2)
True
>>> c2.suit = 's'
>>> c1.suit
'd'
>>> id(c1) == id(c2)
False
更新:我发现了享元模式,它似乎几乎符合要求。但是,我也愿意尝试其他方法。
c1
和c2
是同一个对象。当您在其中一个上设置属性时,没有办法使其变成另一个对象,除非您获取一个新实例并让类给您提供一个新副本。这可能涉及到一种稍微不同的方法,涉及大量的__setattr__
魔法。 - jdi