Reputation: 33
I have a case where I have digit-only code values and some associated standard text. I have a number of fixed code sets I would like to define as enumerations where I can reuse the __new__
method that attaches the associated text to the members (I am using json
to dump these, so want the serialization to reflect the value and not the text), but I am unable to get it work.
Here is my attempt:
import enum
class Code(str):
def __new__(cls, code: str) -> None:
if not code.isdigit():
raise ValueError("code must be digits")
return str.__new__(cls, code)
class CodeEnum(Code, enum.Enum):
def __new__(cls, code: str, text: str) -> None:
obj = Code.__new__(cls, code)
obj._value_ = str(obj)
obj.text = text
return obj
class CodeSet1(CodeEnum):
CODE_0001 = "0001", "Code 0001"
However, I get an AttributeError
:
AttributeError: 'CodeSet1' object has no attribute '_name_'. Did you mean: 'name'?
Is there a way to resolve this such that I can reuse the __new__
method in CodeEnum
for each of my code sets?
Upvotes: 3
Views: 711
Reputation: 69041
The proper definition for CodeEnum
is:
class CodeEnum(Code, enum.Enum):
def __new__(cls, code: str, text: str) -> None:
obj = super().__new__(cls, code)
obj._value_ = Code(code)
obj.text = text
return obj
The major difference is using super()
. _value_
is a Code
instead of just a str
because it should be the same core type as the enum itself.
Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.Upvotes: 2