如何在python中创建不明显的单例对象?

发布于 2025-01-27 09:29:27 字数 767 浏览 2 评论 0原文

我正在尝试创建一个拥有一些数据的类,并在所有代码中“共享”。就像Python中的字符串一样:它们在任何地方都无变处,只有一个具有特定价值的实例。 我想按需创建类,但是每当我使用相同参数创建该类时,我都想获取相同的对象。

我编写了以下代码:

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给我们处理这种情况的所有工具的感觉。

有什么方法可以用dataclass es实现此目标?还是可以实现同样的Pythonic代码?

I'm trying to create a class that holds some data and is "shared" in all the code. Like the strings in Python: they are shared everywhere, as they are immutable, and only one instance with a particular value exists.
I want to create the class on demand, but every time I create that class with the same parameters, I want to get the same object.

I wrote the following code:

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")

It seems to work, but I have a feeling of not using all the tools Python gives us to handle this cases.

Is there any way to implement this with dataclasses? Or a more pythonic code to achieve the same?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人 2025-02-03 09:29:27

您可以使用frozen = true参数定义不变的数据级。制作dataclass 冷冻自动使其可用,因此您可以使用functions.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)

You can define an immutable dataclass with the frozen=True parameter. Making a dataclass frozen automatically makes it hashable, so you can just use functools.cache instead of implementing your own 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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文