gpt4 book ai didi

Python 伪不可变对象(immutable对象)字段

转载 作者:行者123 更新时间:2023-12-01 03:57:31 24 4
gpt4 key购买 nike

我目前需要部分创建一个 Python 对象并能够更新它一段时间。尽管如此,一旦我使用该对象作为字典键,我就不能更新它。

当然有将字段标记为私有(private)的解决方案,这主要是对程序员的警告,我实际上会采用该解决方案。

但是我偶然发现了另一个解决方案,我想知道这是否是一个好主意,或者是否可能会出现严重错误。这是:

class Foo():
def __init__(self, bar):
self._bar = bar
self._has_been_hashed = False

def __hash__(self):
self._has_been_hashed = True
return self._bar.__hash__()

def __eq__(self, other):
return self._bar == other._bar

def __copy__(self):
return Foo(self._bar)

def set_bar(self, bar):
if self.has_been_hashed:
raise FooIsNowImmutable
else:
self._bar = bar

一些测试证明它可以按预期工作,一旦我使用我的对象作为字典键,我就不能再使用 set_bar 了。

你觉得怎么样?这是不是一个好主意?它会反对我吗?有更容易的方法吗?这是一种不好的做法吗?

最佳答案

这样做有点脆弱,因为您永远不知道什么时候可以将某些东西用作字典键,或者什么时候可能会因为其他原因调用它的哈希。对象不应该“知道”它是否被用作字典键。如果仅仅因为其他地方的其他代码将对象放入字典中,代码就可能引发异常,这将是令人困惑的。

遵循“显式优于隐式”的 Python 哲学,为对象提供一个名为 .finalize().lock() 的方法会更安全> 或其他东西,这将设置一个标志,指示该对象是不可变的。您还可以反转异常引发逻辑,以便在对象尚未锁定时 __hash__ 引发异常(而不是在对象已被散列时突变引发异常)。

当您准备好使对象不可变时,您可以调用.lock()。当您完成需要做的任何变异时,显式地将其设置为不可变更有意义,而不是隐含地假设一旦在字典中使用它,就完成了变异。

关于Python 伪不可变对象(immutable对象)字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37194497/

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