gpt4 book ai didi

Python 写时复制行为

转载 作者:太空狗 更新时间:2023-10-29 21:37:51 25 4
gpt4 key购买 nike

我正在解决一个问题,我正在实例化一个对象的许多实例。大多数情况下,实例化的对象是相同的。为了减少内存开销,我想让所有相同的对象指向同一个地址。但是,当我修改对象时,我希望创建一个新实例——本质上是写时复制行为。在 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

更新:我遇到了享元模式,它似乎几乎符合要求。不过,我对其他方法持开放态度。

最佳答案

您是否需要 id(c1)==id(c2) 相同,或者这只是一个演示,真正的目标是避免创建重复的对象?

一种方法是让每个对象都不同,但像上面那样保留对“真实”对象的内部引用。然后,在任何 __setattr__ 调用中,更改内部引用。

我以前从未做过 __setattr__ 的东西,但我认为它看起来像这样:

class MyObj:
def __init__(self, value, suit):
self._internal = Card(value, suit)

def __setattr__(self, name, new_value):
if name == 'suit':
self._internal = Card(value, new_value)
else:
self._internal = Card(new_value, suit)

同样,通过getattr暴露属性。

你仍然有很多重复的对象,但它们后面只有一个“真正的”支持对象的副本。因此,如果每个物体都很大,这会有所帮助,如果它们很轻,这将无济于事,但您有数百万个物体。

关于Python 写时复制行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12359366/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com