gpt4 book ai didi

python - Python 对象的唯一表示

转载 作者:行者123 更新时间:2023-12-05 01:48:07 26 4
gpt4 key购买 nike

设 C 是一个 Python 类,并假设 C 的构造函数接受一个整数作为参数。

现在考虑说明

x = C(0)
y = C(0)

Python 的默认行为意味着 x 和 y 在内存中占据两个不同的位置。

Is it possible to force x and y to share the same place in memory?

如果有 Python 装饰器能胜任这项工作,我将非常高兴。

[注意] 我正在寻找一种内存构造函数的方法(有关函数的内存,请参阅 http://en.wikipedia.org/wiki/Memoization)。

[Add] Sage Open Source Mathematics Software 通过类UniqueRepresentation 为这个问题提供了很好的解决方案(参见here)。任何类都应继承自该类以具有预期的行为。不过,我想知道是否有针对此问题的纯 Python 解决方案。

最佳答案

您可能想使用 lru_cache .如果你的类定义是

@lru_cache(maxsize=32)
class C(object):
def __init__(self, num):
self.num = num

然后它的行为就像

>>> a = C(1)
>>> a.num = 2
>>> b = C(1)
>>> b.num
2
>>> a is b
True

但是,这使得名称 C 成为一个函数,并且在实际实例化该类之前,任何类功能都无法使用。如果你愿意,你也可以直接缓存负责创建对象的方法__new____new__ 是一个方法,它接受与 __init__ 相同的所有参数,当我们创建类实例时,它在 __init__ 之前被调用。

由于缓存 __new__ 的输出很简单,我们可以让事情变得更有趣。让我们创建一个新的装饰器,它的工作方式与 lru_cache 类似,但它可以与类一起使用来缓存 __new__ 的输出:

def lru_cache_class(maxsize):
def wrap(klass):
@lru_cache(maxsize=maxsize)
def new(cls, *args, **kwargs):
self = object.__new__(cls)
return self
klass.__new__ = new
return klass
return wrap

我们给 __new__ 所有可能的参数和关键字参数,以便它也可以与其他类一起使用。现在我们可以像这样缓存 C2 类的实例:

@lru_cache_class(maxsize=32)
class C2(object):
def __init__(self, num):
self.num = num

我们可以看到对象被缓存了:

>>> c = C2(2)
>>> c is C2(2)
True

但是,与第一种方法相比,这种方法还有另一个细微差别。例如:

>>> d = C2(3)
>>> d.num = 4
>>> d.num
4
>>> e = C2(3)
>>> d.num == e.num
>>> d.num
3

此行为是预期的,因为无论如何都会调用 __init__,尽管对象的内存位置保持不变。根据您的用例,您可能还想缓存 __init__ 的输出。

关于python - Python 对象的唯一表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18498756/

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