如何在Python中创建不可变的列表(或其他值):真正的常量?
在一个旧讨论中,我发现提到了输入Final
的内容。我试了试文档中的例子:
y: Final[Sequence[str]] = ['a', 'b']
y.append('x') # Error: "Sequence[str]" has no attribute "append"
z: Final = ('a', 'b') # Also works
但是和文档说的不一样的是,它把y
改成了['a','b','x']
,没有报错。我现在用的是Python 3.11。这是怎么回事?而且,2024年在Python中创建不可变常量的最新方法是什么呢?
目前我使用@dataclass(frozen=True)
来实现不可变性,但可能还有更简单的方法。
旧讨论对Python 3.10+的现代特性没有帮助。
1 个回答
3
类型检查器只能在代码运行前给你一些提示,告诉你这里可能有问题。在代码运行时,Python解释器并不在乎类型提示说了什么。(当然,如果你使用像Pydantic这样的库,它会强制执行这些规则,但这不是我们要讨论的内容)
接下来我们聊聊 Final
。根据文档的解释:
typing.Final
是一个类型标记,用来表示一个变量或属性不应该被重新赋值、重新定义或覆盖。
这里说的是给标签 y
赋值的问题!而不是改变 y
指向的对象。使用 .append()
方法是对对象的“修改”。你仍然让 y
指向同一个列表,所以这并不会阻止你。因此你不会看到任何相关的错误。这个错误来自于 Sequence
。如果你想修改一个序列,你应该使用 MutableSequence
。
你可以用 tuple
来代替可变列表(虽然它们还有其他不同之处),或者自己创建一个类似列表的类:https://stackoverflow.com/a/22340603/13944524