【问题标题】:Can I create an Enum of a dataclass instances?我可以创建数据类实例的枚举吗?
【发布时间】:2022-11-09 23:47:07
【问题描述】:

我有一组固定的三个传感器,我想将它们建模为枚举。这些传感器中的每一个都由几个不同的属性参数化。因此,我想将传感器本身建模为数据类。

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

@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=...)

我的期望是这应该本质上创建一个枚举,该枚举的实例的行为类似于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

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

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

【问题讨论】:

  • Sensors 继承自 SensorLocation 并没有真正意义,你想通过这样做来完成什么?你能详细说明吗? “这意味着当使用 MyPy 或类似工具时,我失去了一些输入提示正确值的能力”
  • 您也许可以创建一个 Enum,其值是冻结的数据类实例。

标签: python enums python-dataclasses


【解决方案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={'foo': 'bar1'})
    BOTTOM_SENSOR = SensorLocation(address=0x10, pins=0xf0,  other_details={'foo': 'bar2'})
    SIDE_SENSOR = SensorLocation(address=0x15, pins=0xf,  other_details={'foo': 'bar3'})

    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}')

输出:

Top sensor address: 0x10

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多