如何在 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 提供的所有工具来处理这种情况。
有什么方法可以用 dataclass
es 实现吗?或者更多的 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)
我正在尝试创建一个 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 提供的所有工具来处理这种情况。
有什么方法可以用 dataclass
es 实现吗?或者更多的 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)