我可以创建数据类实例的枚举吗?

Joh*_*ohz 6 python enums python-dataclasses

我有一组固定的三个传感器,我想将其建模为枚举。每个传感器都通过一些不同的属性进行参数化。因此,我想将传感器本身建模为数据类。

我天真的尝试看起来像这样:

@dataclass
class SensorLocation:
    address: int
    pins: int
    other_details: ...

class Sensors(SensorLocation, Enum):
    TOP_SENSOR = SensorLocation(address=0x10, pins=0xf,  other_details=...)
    BOTTOM_SENSOR = SensorLocation(address=0x10, pins=0xf0,  other_details=...)
    SIDE_SENSOR = SensorLocation(address=0x15, pins=0xf,  other_details=...)
Run Code Online (Sandbox Code Playgroud)

我的期望是,这本质上应该创建一个枚举,其中该枚举的实例的行为类似于SensorLocation. 这使得类型更加清晰,并将方法放在我期望的位置。

但是,在创建枚举时失败,并出现错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/path/to/python/3.7.10/lib/python3.7/enum.py", line 232, in __new__
    enum_member.__init__(*args)
  File "<string>", line 3, in __init__
  File "/path/to/python/3.7.10/lib/python3.7/types.py", line 175, in __set__
    raise AttributeError("can't set attribute")
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)

我能做的是删除SensorLocation枚举声明中的子类化,但这意味着当使用 MyPy 或类似工具时,我失去了键入提示正确值的能力。它还使访问实际值变得更加复杂,但该枚举的主要目的是提供对这些值的访问。

有没有办法解决我缺少的这个错误,或者我现在看不到的其他解决方案?

roh*_*lfs 1

我认为您可以尝试__init__为您的枚举使用自定义函数:

from dataclasses import dataclass
from enum import Enum


@dataclass
class SensorLocation:
    address: int
    pins: int
    other_details: dict


class Sensors(SensorLocation, Enum):
    TOP_SENSOR = SensorLocation(address=0x10, pins=0xf, other_details={})
    BOTTOM_SENSOR = SensorLocation(address=0x10, pins=0xf0, other_details={})
    SIDE_SENSOR = SensorLocation(address=0x15, pins=0xf, other_details={})

    def __init__(self, data: SensorLocation):
        for key in data.__annotations__.keys():
            value = getattr(data, key)
            setattr(self, key, value)


print(f'Top sensor address: 0x{Sensors.TOP_SENSOR.address:x}')
Run Code Online (Sandbox Code Playgroud)

输出:

Top sensor address: 0x10
Run Code Online (Sandbox Code Playgroud)