Re: Behaviour of enumerated types (was: Re: Immutable instances, constant values)



On Fri, 18 Nov 2005 23:43:10 +1100 (EST), Ben Finney <bignose+hates-spam@xxxxxxxxxxxxxxx> wrote:

>Bengt Richter <bokr@xxxxxx> wrote:
>> Ben Finney <bignose+hates-spam@xxxxxxxxxxxxxxx> wrote:
>> >I've recently packaged 'enum' in PyPI.
>> [...]
>> My notion of enum comes from (what I remember of) Pascal
>
>You might want to investigate the 'enum' package for my idea of how an
>enumerated type can work.
I guess I saw an earlier version, and got confused as to the goal, sorry.
I will look in PyPI.
>
>> which is basically an ordered set of names of integers forming a
>> type, and ord(one_of_the_names) gets you the index value.
>
>Getting a numeric index might be useful in a language such as Pascal,
>with no built-in dict or sequence types. In Python, where any
>immutable object can be a dict key, and any sequence can be iterated,
>it seems of no use.
Does your concept of enumeration not have a fixed order of a set of names?
If it does, what is more natural than using their index values as keys
to other ordered info? OTOH, the index values (and hence my enums) are[1] not
very good as unique dict keys, since they compare[2] promiscuously with each other
and other number types. Hm, maybe if hash were defined class-unique, e.g.,
def __hash__(self): return hash((int(self), type(self).__name__)
Ok, did that, _seems_ to work (fixed __repr__ too):
[1] were & [2] compared ;-)

>>> from makeenum import makeEnum
>>> Few = makeEnum('Few','zero one two three')
>>> Few()
Few('zero')
>>> d = dict((Few(n), Few.names.index(n)) for n in Few.names)
>>> d
{Few('zero'): 0, Few('three'): 3, Few('one'): 1, Few('two'): 2}
>>> d[1]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
KeyError: 1
>>> d[Few(1)]
1

But still can work as integer:
>>> 'ABC'[Few(1)]
'B'
>>> 'ABC'[Few('one')]
'B'
>>> 'ABC'[Few('two')]
'C'

>
>> But what we have is named integers, much as True and False are built
>> in names for integer subtypes with value 1 and 0.
>
>That's an implementation detail; surely code shouldn't be expecting
>any particular relationship between integers and boolean values?
Au contraire, much code depends on it, e.g.,

>>> def verboselen(s): return '%r has %d element%s'%(s, len(s), ('s','')[len(s)==1])
...
>>> verboselen(range(3))
'[0, 1, 2] has 3 elements'
>>> verboselen(range(0))
'[] has 0 elements'
>>> verboselen(range(1))
'[0] has 1 element'

>>> type(len(range(3))==1)
<type 'bool'>
>>> type(len(range(3))==1).mro()
[<type 'bool'>, <type 'int'>, <type 'object'>]
>>> int (len(range(3))==1)
0
>>> int (len(range(1))==1)
1

>
>> So I'd say enums should also be int subtypes...
>
>Likewise, that seems best left as an implementation detail. Why expect
>any particular mapping to int values? Doing arithmetic or boolean
>logic on enumerated values seems against their purpose.
I guess I will have to look at your enum in PyPI to understand what
you mean by "their purpose" ;-)

To me the int correspondence is as expectable and natural as a,b,c=range(3)
(at least as a default) though I think different enumerations should be
different types. Note that the ordering of int values makes the instances
nicely sortable too, e.g.,

>>> d.items()
[(Few('zero'), 0), (Few('three'), 3), (Few('one'), 1), (Few('two'), 2)]
>>> sorted(d.items())
[(Few('zero'), 0), (Few('one'), 1), (Few('two'), 2), (Few('three'), 3)]

or more directly

>>> d.keys()
[Few('zero'), Few('three'), Few('one'), Few('two')]
>>> sorted(d.keys())
[Few('zero'), Few('one'), Few('two'), Few('three')]

Enumerations defined as monotonic but non-contiguous sequences of named int
values are conceivable too. They can be useful in defining bit masks with
distinguishable types, but that act like ints. Kind of a sparse enumeration.
Maybe I'll add that in.

But bottom line, I really thing the int base type is more than an implementation
detail. I think it's natural for an _ordered_ set of names ;-)

I'll go look at PyPI now ;-)

Regards,
Bengt Richter
.



Relevant Pages

  • Re: enum type int or unsigned int?
    ... that have type int and may appear wherever such are permitted. ... values of all the members of the enumeration. ... "enum" types are declared via the following syntax: ... so the loop will continue to run. ...
    (comp.lang.c)
  • Re: enum type int or unsigned int?
    ... that have type int and may appear wherever such are permitted. ... values of all the members of the enumeration. ... "enum" types are declared via the following syntax: ... so the loop will continue to run. ...
    (comp.lang.c)
  • Re: Variable arguments of enum type
    ... the implementation type used for the enumeration type as a whole. ... I used (unsigned int) instead of against the off chance that the ... enum EnumType1 { ... enum EnumType2 can be distinct from enum EnumType1; ...
    (comp.lang.c)
  • Re: Behaviour of enumerated types
    ... If you want sequence numbers, ... the enum object itself can be used directly as an iterable. ... an enumeration is an instance of Enum. ... have special methods of their own, and inherit methods from int). ...
    (comp.lang.python)
  • Immutable instances, constant values
    ... Howdy all, ... I've recently packaged 'enum' in PyPI. ... enumeration values are "constant" values. ...
    (comp.lang.python)