python - 使用自定义混合类型创建枚举

标签 python oop enums

relevant section Python Enum 文档中提到,混合类型可用于确保项目属于该类型并充当该类型的对象,如示例所示:

class IntEnum(int, Enum):
    pass

但是,文档没有给出任何关于如何使用自定义类作为混合类型的示例,而我在这方面失败了。有可能吗?如果是这样,我该怎么做?


我要编写的代码是

@dataclass
class Field:
    dtype: str
    name: str

@dataclass
class FwfField(Field):
    width: int

    def __post_init__(self):
        if self.width <= 0:
            raise ValueError("Field width must be positive.")

class CnefeSchema(FwfField, Enum):
    state_code = ("int", "Código da UF", 2)
    ...

当我从另一个文件导入 CnefeSchema 或运行它时,我得到

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [1], in <cell line: 1>()
----> 1 from src.conf.schemas import CnefeSchema

File src/conf/schemas.py:25, in <module>
     21     pass
     24 # TODO automatically read schema from Layout
---> 25 class CnefeSchema(EnumFwfField, Enum):
     27     @classmethod
     28     def parse(cls) -> tuple[list, dict, dict]:
     29         """
     30         Get field widths, dtypes, and columns from schema.
     31
   (...)
     34         as `pandas.read_fwf`.
     35         """

File /usr/lib/python3.10/enum.py:298, in EnumMeta.__new__(metacls, cls, bases, classdict, **kwds)
    296 enum_member._name_ = member_name
    297 enum_member.__objclass__ = enum_class
--> 298 enum_member.__init__(*args)
    299 # If another member with the same value was already defined, the
    300 # new member becomes an alias to the existing one.
    301 for name, canonical_member in enum_class._member_map_.items():

File <string>:4, in __init__(self, dtype, name, width)

File /usr/lib/python3.10/types.py:187, in DynamicClassAttribute.__set__(self, instance, value)
    185 def __set__(self, instance, value):
    186     if self.fset is None:
--> 187         raise AttributeError("can't set attribute")
    188     self.fset(instance, value)

AttributeError: can't set attribute

我已经尝试过:

  • 定义另一个类,EnumFwfField,并将其用作混合类,即
    class EnumFwfField(FwfField, Enum):
        pass
    
    class CnefeSchema(EnumFwfField, Enum):
        ...
    
    但我得到了与上面相同的错误;
  • Enum 字段(在本例中为 state_code)设置为 FwfField,即
    class CnefeSchema(FwfField, Enum):
        state_code = FwfField("int", "Código da UF", 2)
        ...
    
    但后来我得到
    Traceback (most recent call last):
      File "src/conf/schemas.py", line 25, in <module>
        class CnefeSchema(EnumFwfField, Enum):
      File "/usr/lib/python3.10/enum.py", line 298, in __new__
        enum_member.__init__(*args)
    TypeError: FwfField.__init__() missing 2 required positional arguments: 'name' and 'width'
    

最佳答案

您遇到的问题是因为在上面的代码中,您的 Field 数据类中有一个 name 属性,但 Enum 不会让您设置了一个 name 属性。

将该字段重命名为其他名称,例如 'dname',它应该可以工作。

(3.11中的错误消息信息更丰富。)

关于python - 使用自定义混合类型创建枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72652675/

相关文章:

c# - 为什么 MSDN 声明 HasFlag *设计*用于与 FlagsAttribute 一起使用?

enums - Thrift 默认枚举值

java - jaxb 中枚举类型的解码

python - 为什么会出现这个输出?

javascript - 试图避免重复,简化...创建全局变量并简化我的 javascript -- 纯 js 没有 jquery

java - new 关键字的本地使用

C++:跟踪类对象

python - 无法安装 pyOpenSSL

python - 在 Python 中反转字符串但保留数字的原始顺序

python - 绘制一年时间序列中的每周滴答数据