如何在 python 中创建不可变对象和单例对象?

How to create inmutable and singleton objects in python?

我正在尝试创建一个 class 来保存一些数据并在所有代码中“共享”。就像 Python 中的字符串一样:它们随处共享,因为它们是不可变的,并且只有一个具有特定值的实例存在。 我想按需创建 class,但每次我使用相同的参数创建 class 时,我都想获得相同的对象。

我写了下面的代码:

class Data:

    _instances: dict[str, "Data"] = {}

    def __new__(cls, data: str) -> "Data":
        if data not in cls._instances:
            cls._instances[data] = super().__new__(cls)

        return cls._instances[data]

    def __init__(self, data: str) -> None:
        self._data = data

    @property
    def data(self) -> str:
        return self._data

    @data.setter
    def data(self, data: str) -> None:
        raise KeyError("Cannot change an immutable object")

似乎可行,但我感觉没有使用 Python 提供的所有工具来处理这种情况。

有什么方法可以用 dataclasses 实现吗?或者更多的 pythonic 代码来实现相同的?

您可以使用 frozen=True 参数定义不可变数据类。使数据类 frozen 自动使其可散列,因此您可以只使用 functools.cache 而不是实现自己的缓存:

from dataclasses import dataclass
from functools import cache

@dataclass(frozen=True)
class Data:
    data: str

    @cache
    def __new__(cls, data: str) -> "Data":
        return super().__new__(cls)

x = Data("foo")
y = Data("foo")
assert id(x) == id(y)