[Python-ideas] Enums

M.-A. Lemburg mal at egenix.com
Fri Jul 29 19:40:14 CEST 2011


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.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Jul 29 2011)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::


   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/



More information about the Python-ideas mailing list