
Adam Johnson wrote:
Peeking at the source for Enum, the __new__ method is explicitly called, thereby deferring the call to __init__ until it, too, is explicitly called, but only after member's _name_ attribute has been assigned. So, adapting your example: class ChoiceEnum(Enum): def __init__(self, value): self.label = self.name.capitalize() class Color(ChoiceEnum): SMALL = 'S' MEDIUM = 'M' LARGE = 'L' print(Color.SMALL.label) # Prints 'Small' Side note: I was surprised to find the docs lacking a clear example to explain this behaviour, the DuplicateFreeEnum recipe does show that members' name/_name_ attributes can be accessed, via the __init__, but that info could have more attention drawn to it rather than being somewhat buried in an example where it isn't necessarily immediately obvious. This is especially true considering the specific "When to use __new__() vs. __init__()" section, which reads:
__new__() must be used whenever you want to customize the actual value of the Enum member. Any other modifications may go in either __new__() or __init__(), with __init__() being preferred. The second sentence, as per this thread, is demonstrably untrue. Modifications that are reliant upon the name of the member must go in __init__ (in cases where _generate_next_value_ & auto() are inappropriate).
Thanks for this. It comes close to answering my concern. There's one case that's very useful (IMO) that it still doesn't handle though. There's still no way to have the value and the label each be _optionally_ based on the name. Using `_generate_next_value_`, both the value and the label could be based on the name, but then any means of trying to override the label would mean not using `auto()` and therefore not having access to name `__new__`, and we're not allowed to modify the value in `__init__` where the name _is_ available.