On Fri, 18 Nov 2005 23:43:10 +1100 (EST), Ben Finney <[EMAIL PROTECTED]> wrote:
>Bengt Richter <[EMAIL PROTECTED]> wrote: >> Ben Finney <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list