[Python-ideas] Enums

Guido van Rossum guido at python.org
Fri Jul 29 19:56:50 CEST 2011


On Fri, Jul 29, 2011 at 10:40 AM, M.-A. Lemburg <mal at egenix.com> wrote:
> M.-A. Lemburg wrote:
>> Guido van Rossum wrote:
>>> On Fri, Jul 29, 2011 at 7:55 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>>> On Fri, Jul 29, 2011 at 7:37 PM, M.-A. Lemburg <mal at egenix.com> wrote:
>>>>> Paul Colomiets wrote:
>>>>>> The problem with named value is that:
>>>>>>>>>>>>     namedvalue(1, "red")
>>>>>>>>>>>> Will give you are repr of "red". And you don't know whether it's
>>>>>> TerminalColors.red or WebSafe.red or BuildbotState.red. And
>>>>>> most of us will be too lazy to add group name or module name
>>>>>> directly into the named value (partially because it's repeating
>>>>>> yourself).
>>>>>>>>>>>> So the big feature of flufl.enum is classname (call it group
>>>>>> name) in repr and isinstance check.
>>>>>>>>>> A meta class variant could easily add class and module
>>>>> names to the attrbute name, if needed/wanted.
>>>>>>>> Given that the status quo is for "TerminalColors.red" et al to just
>>>> display as "1" (or whatever integers they're assigned), I'm finding it
>>>> hard to consider this a particularly significant criticism. If we
>>>> don't even know what *kind* of values are being passed to a debugging
>>>> message, we have bigger problems than whether or not those values have
>>>> been given names (and searching for all named values of 'red' with a
>>>> value of '1' is going to create a much smaller resulting set than
>>>> searching for all values of '1' ).
>>>>>>>>> Just to make sure:
>>>>>>>>>> namedvalue() will just change the repr() of the value, not
>>>>> the str() of it, right ?
>>>>>>>> Yeah, I figured out the mechanics needed to make that work properly
>>>> when writing up the recipe for the cookbook
>>>> (http://code.activestate.com/recipes/577810-named-values/)
>>>>>>>>> I think that's essential for making namedvalue()s useful
>>>>> in practice, since you mostly need this for debugging
>>>>> and error reporting and don't want the namevalue aspect
>>>>> of a constant to get in the way of its normal use in
>>>>> e.g. conversion to text formats such as JSON, XML, etc.
>>>>>>>> Yeah, the case I first thought of was writing numbers to CSV files,
>>>> but it's really any data export operation.
>>>>>> That's assuming the data export format doesn't support enums.
>>>>>> I would fine enums whose str() is just an int pretty annoying. Note
>>> that str(True) == repr(True) == 'True' and that's how I'd like it to
>>> be for enums in general. If you want the int value, use int(e). If you
>>> want the class name, use e.__class__.__name__ (maybe e.__class__ is
>>> what you're after anyway). My observation is that most enums have
>>> sufficiently unique names that during a debugging session the class is
>>> not a big mystery; it's the mapping from value to name that's hard to
>>> memorize. As a compromise, I could live with str(e) == 'red' and
>>> repr(e) == 'Color.red'. But I don't think I could stomach str(e) == 1.
>>>> The situation with enums is different than for booleans: many
>> data interchange formats out there support true/false directly,
>> so there's little to change and little breakage involved.
>> And it's easy to fix, since you only to deal with two such
>> enums.
>>>> However, when you change existing code constants to enums,
>> chances are high that your interchange libraries are going
>> to fail because of this, or your application will start
>> providing broken data to external resources, without you
>> knowing.
>>>> Since it's easy to switch from %s to %r, if needed, I don't
>> see much of a problem with having str(e) continue to return
>> the integer string.
>>>> Regarding the repr(e): This should really be user-defined.
>> There situations where you want to see both the integer
>> code and description in the repr(e), e.g. when dealing with
>> error codes where you quickly need to communicate the
>> error, so a format like '[123] Error contacting server'
>> would be better than just 'Error contacting server'.
>>>> In other cases, the subsystem is important, so getting
>> '[Server][FTP] Permission error' is more useful than
>> just 'Permission error'.
>>>> And in yet other circumstances, you want to see the
>> defining module and class.
>> Thinking about this some more: it would be good
> to have attributes
>>  .name - namedvalue name
>  .value - namedvalue value object
>> on enums and have str(e) == str(e.value) and
> repr(e) == e.name.
>> BTW: Would it be possible to have work for more than just
> integers ? If not, "namedint" may be a more intuitive name.

Nick's proposal for named values is to work for any type. But I think
that the things called enums ought to be an int subclass. I guess if
enums are named values their value attribute should return a plain int
with the same value.
-- 
--Guido van Rossum (python.org/~guido)


More information about the Python-ideas mailing list

AltStyle によって変換されたページ (->オリジナル) /