Я хотел бы создать перечисление структурированных объектов.
Один из способов сделать это — использовать класс данных, и он работает:
Код: Выделить всё
from dataclasses import dataclass
from enum import Enum
from typing_extensions import assert_never
@dataclass(frozen=True)
class _BaseInstTypeDataclass:
instance_type: str
display_name: str
class InstTypeDataClass(_BaseInstTypeDataclass, Enum):
t2_micro = ("t2.micro", "t2.micro: Cheap!")
r7i_2xlarge = ("r7i.2xlarge", "r7i.2xlarge: Expensive!")
assert list(InstTypeDataClass) == [
InstTypeDataClass.t2_micro,
InstTypeDataClass.r7i_2xlarge,
]
assert isinstance(InstTypeDataClass.t2_micro, InstTypeDataClass)
# This function type checks
def f_dataclass(e: InstTypeDataClass):
if e == InstTypeDataClass.t2_micro:
...
elif e == InstTypeDataClass.r7i_2xlarge:
...
else:
assert_never(e)
Однако с attrs...:
Код: Выделить всё
import attrs
@attrs.define(frozen=True)
class _BaseInstTypeAttrs:
instance_type: str
display_name: str
class InstTypeAttrs(_BaseInstTypeAttrs, Enum):
t2_micro = ("t2.micro", "t2.micro: Cheap!")
r7i_2xlarge = ("r7i.2xlarge", "r7i.2xlarge: Expensive!")
# This function type checks
def f_attrs(e: InstTypeAttrs):
if e == InstTypeAttrs.t2_micro:
...
elif e == InstTypeAttrs.r7i_2xlarge:
...
else:
assert_never(e)
Код: Выделить всё
$ python foo.py
_BaseInstTypeDataclass(instance_type='foo', display_name='bar')
Traceback (most recent call last):
File "foo.py", line 58, in
class InstTypeAttrs(_BaseInstTypeAttrs, Enum):
File "/Users/.../python3.10/enum.py", line 287, in __new__
enum_member._value_ = value
File "/Users/.../python3.10/site-packages/attr/_make.py", line 551, in _frozen_setattrs
raise FrozenInstanceError()
attr.exceptions.FrozenInstanceError
Подробнее здесь: https://stackoverflow.com/questions/791 ... trs-doesnt