如何在python中创建不明显的单例对象?
我正在尝试创建一个拥有一些数据的类,并在所有代码中“共享”。就像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 dataclass
es? Or a more pythonic code to achieve the same?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
frozen = true
参数定义不变的数据级。制作dataclass冷冻
自动使其可用,因此您可以使用functions.cache
而不是实现自己的缓存:You can define an immutable dataclass with the
frozen=True
parameter. Making a dataclassfrozen
automatically makes it hashable, so you can just usefunctools.cache
instead of implementing your own cache: