Python:数据类的唯一整数?
Python: uniqe integer for dataclass?
我有以下数据class。
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
我想要的是,每次我创建这个 class 的对象时,它都会标有一个从 0 开始递增的唯一 ID。
所以,我第一次说 first = myDataClass(0, 1)
那么我应该得到 first.id == 0
,然后如果我说 second = myDataClass(0, 1)
,我应该得到 second.id == 1
.
冻结数据类有点棘手,因为您编写的任何动态更新字段的代码都会遇到 FrozenInstanceError
,但这当然是可能的:
from dataclasses import dataclass, field
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
id: int = field(init=False)
def __post_init__(self):
if not hasattr(myDataClass, "_COUNT"):
myDataClass._COUNT = 0
object.__setattr__(self, "id", myDataClass._COUNT)
myDataClass._COUNT += 1
哪个应该如您所愿:
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=0)
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=1)
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=2)
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=3)
您可以将 default_factory
用于数据的属性class,并使用 class 变量来跟踪所使用的最大 ID。
from dataclasses import dataclass, field
from typing import ClassVar
def _assign_id():
new_id = myDataClass._next_id
myDataClass._next_id += 1
return new_id
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
id: int = field(default_factory=_assign_id, init=False)
_next_id: ClassVar[int] = 0
可以通过使用 an itertools.count()
instance's __next__
method 作为字段的 default_factory
来生成线程安全的唯一 ID:
from dataclasses import dataclass, field
from itertools import count
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
id: int = field(default_factory=count().__next__, init=False)
它比其他选项更快,不涉及自定义代码,并且至少在 CPython 参考解释器上是线程安全的(itertools.count
在 C 中实现并且不发布 GIL,因此没有两个实例获得相同结果的几率 id
).
我有以下数据class。
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
我想要的是,每次我创建这个 class 的对象时,它都会标有一个从 0 开始递增的唯一 ID。
所以,我第一次说 first = myDataClass(0, 1)
那么我应该得到 first.id == 0
,然后如果我说 second = myDataClass(0, 1)
,我应该得到 second.id == 1
.
冻结数据类有点棘手,因为您编写的任何动态更新字段的代码都会遇到 FrozenInstanceError
,但这当然是可能的:
from dataclasses import dataclass, field
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
id: int = field(init=False)
def __post_init__(self):
if not hasattr(myDataClass, "_COUNT"):
myDataClass._COUNT = 0
object.__setattr__(self, "id", myDataClass._COUNT)
myDataClass._COUNT += 1
哪个应该如您所愿:
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=0)
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=1)
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=2)
>>> (myDataClass(1.0,2.0))
myDataClass(x=1.0, y=2.0, id=3)
您可以将 default_factory
用于数据的属性class,并使用 class 变量来跟踪所使用的最大 ID。
from dataclasses import dataclass, field
from typing import ClassVar
def _assign_id():
new_id = myDataClass._next_id
myDataClass._next_id += 1
return new_id
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
id: int = field(default_factory=_assign_id, init=False)
_next_id: ClassVar[int] = 0
可以通过使用 an itertools.count()
instance's __next__
method 作为字段的 default_factory
来生成线程安全的唯一 ID:
from dataclasses import dataclass, field
from itertools import count
@dataclass(frozen=True)
class myDataClass:
x: float
y: float
id: int = field(default_factory=count().__next__, init=False)
它比其他选项更快,不涉及自定义代码,并且至少在 CPython 参考解释器上是线程安全的(itertools.count
在 C 中实现并且不发布 GIL,因此没有两个实例获得相同结果的几率 id
).