[Python-ideas] Allow Enum members to refer to each other during execution of body

Ethan Furman ethan at stoneleaf.us
Tue Jul 9 02:12:35 CEST 2013


On 07/08/2013 02:27 PM, Antony Lee wrote:
> Currently, during the execution of the body of the Enum declaration, member names are bound to the values, not to the
> Enum members themselves.  For example
>
> class StateMachine(Enum):
>      A = {}
>      B = {1: A} # e.g. a transition table
>
> StateMachine.B[1] == {}, when one could have expected StateMachine.B[1] == StateMachine.A
>
> It seems to me that a behavior where member names are bound to the members instead of being bound to the values is more
> useful, as one can easily retrieve the values from the members but not the other way round (at least during the
> execution of class body).
>
> Initially, I thought that this could be changed by modifying _EnumDict, so that its __setitem__ method sets the member
> in the dict, instead of the value, but in fact this doesn't work because while the values are being set in the _EnumDict
> the class itself doesn't exist yet (and for good reason: the __init__ and __new__ methods may be defined later but there
> is no way to know that).  However, a possible solution could to momentarily create Enum members as instances of some
> dummy class, and then later, after execution of class body has completed, change the members' class to the actual Enum
> and initialize them as needed (if an __init__ or a __new__ are actually defined).  Well, there are limitations with this
> approach (e.g. the members are not fully initialized before class body finishes to execute) but this seems better than
> the current behavior(?)

Part of the problem here would be maintaining the linkage when the temp enum object from _EnumDict was translated into 
an actual Enum member.

One possible work around is to store the name of the member instead:

   class StateMachine(Enum):
       A = {}
       B = {1:'A'}

then the other methods can either dereference the name with an __getitem__ look-up, or the class can be post-processed 
with a decorator to change the strings back to actual members... hmmm, maybe a post_process hook in the metaclass would 
make sense?

--
~Ethan~


More information about the Python-ideas mailing list