使用自定义混合类型创建枚举
在文档,提到混合类型可用于确保项目属于该类型并充当该类型的对象,例如:
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
,并使用它作为混合,即 在 经过 类Cnefeschema(Enumfwfffield,Enum): ... 但是我得到的错误与上面相同; - 将
enum
fields设置(在此示例中,state_code
)为fwffield
,即类Cnefeschema(fwffield,Enum) state_code = fwffield(“ int”,“códigoda uf”,2) ...
In the relevant section of the Python Enum
documentation, it is mentioned that mix-in types can be used to ensure items belong to that type and act as objects of that type, like in the example:
class IntEnum(int, Enum):
pass
However, the documentation does not give any examples on how to use a custom class as a mix-in type, and I've failed miserably at that. Is it even possible? And if so, how do I do it?
The code I'm trying to write is
@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)
...
When I import CnefeSchema
from another file or run it, I get
---------------------------------------------------------------------------
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
I've already tried:
- Defining another class,
EnumFwfField
, and using it as a mix-in, i.e.class EnumFwfField(FwfField, Enum): pass class CnefeSchema(EnumFwfField, Enum): ...
but I get the same error as above;
- Setting the
Enum
fields (in this example,state_code
) toFwfField
, i.e.class CnefeSchema(FwfField, Enum): state_code = FwfField("int", "Código da UF", 2) ...
but then I get
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'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您存在的问题是因为在上面的代码中,您在
name
属性 field dataclass中具有名称
属性。将该字段重命名为其他东西,例如
'dname'
,它应该起作用。(3.11中的错误消息更具信息性。)
The issue you are having is because in your above code you have a
name
attribute in yourField
dataclass, butEnum
will not let you set aname
attribute.Rename that field to something else, for example
'dname'
, and it should work.(The error message in 3.11 is more informative.)