Steven D'Aprano wrote:
> On Sat, Nov 30, 2019 at 08:24:39AM -0000, Steve Jorgensen wrote:
> > Basically, with the current implementation of
> > Enum and supporting 
> > classes, the only way that a member can have access to its own name 
> > during or prior to its initialization is if/when its value is 
> > auto-generated, so if you want to specify a value rather than having 
> > it auto-generated (e.g. to generate a label attribute) then there's no 
> > convenient way to do it.
> > Code speaks louder than words. Can you give an example of what you are 
> trying to do? If I'm reading you correctly, we can already specify 
> values:
> py> class Colours(Enum):
> ...     red = auto()
> ...     green = 999
> ...
> py> Colours.red, Colours.green
> (<Colours.red: 1>, <Colours.green: 999>)
> 
> so I'm not really sure what you want or how you are doing it. Can we 
> pretend you are reporting a bug, and ask what did you do, what did you 
> expect, and what happened instead?
> > One can work around that by writing the code to make
> > use of the name 
> > property after installation, but why should we force the developer to 
> > write code in an awkward manner when we could simply make the name 
> > available to the `__new__ method.
> > Whose __new__ method?
> [...]
> > The idea that comes to mind is to pass a
> > context object argument to 
> > __new__ with name and names attributes. To preserve
> > backward 
> > compatibility, there could be have a class attribute named something 
> > like _use_context_ (False by default) to enable or disable
> > passing 
> > that parameter.
> > That sounds convoluted, complicated and confusing. Are there existing 
> examples where we do that?
> I would think if we need an backwards-incompatible breaking change, 
> there are three better ways:
> 
> a subclass of Enum that does what you want;
> 
> following a period of deprecation, have a flag-day change to the new 
> behaviour (3.9 is probably too soon, but 3.10 might be possible);
> 
> a __future__ import (although that generally only applies to syntax.
> 
> 
> especially the first.

Per the `AutoName` example at 
https://docs.python.org/3/library/enum.html#using-automatic-values, one can 
easily use `_generate_next_value_` to derive a member's value from its name, 
but that is only invoked when the object's value is an instance of `auto()`, so 
if you want to give an enum member an explicit value _and_ have an attribute 
such as `label` derived from its name, that's a hard nut to crack.

An example usage of what I'm suggesting would be something like…

    class ChoiceEnum(Enum):
        _use_context_ = True
        
        def __new__(cls, value, context):
            obj = object.__new__(cls)
            obj._value_ = value
            obj.label = context.name.capitalize()
    
    class Color(ChoiceEnum):
        SMALL = 'S'
        MEDIUM = 'M'
        LARGE = 'L'
    
    print(Color.SMALL.label)  # Prints 'Small'
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/34WVVUNN7LMF2HT3ILUA3Q2AL2M4JJMK/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to