new enum idiom
Jonathan Polley
Sun Jan 7 15:23:07 EST 2001
Forget about the ordinal/value conversion, I keep thinking in terms of strongly typed
languages (sigh). I have also modified the enum function so that it no longer needs to
be passed a class, but instantiates one of its own and returns it to the caller.
>>> MIDI_Event = enum.enum ("NOTE_ON", "NOTE_OFF", 3, "POLYPHONIC_KEY_PRESSURE",
"CONTROLLER_CHANGE")
>>> MIDI_Event.NOTE_ON
0
>>> MIDI_Event.POLYPHONIC_KEY_PRESSURE
4
Jonathan Polley
jwpolley at collins.rockwell.com
# module begins
import types
# a private class that will be instantiated for each enumeration
class __Enum_Class:
# an empty constructor
def __init__(self):
pass
# print out the name of the base class, FWIW
def __repr__(self):
return `self.__class__`
def enum(*args, **keys):
"""Create and enumerate to your hearts delight,
args is a sequence of enumeration names, possibly interleaved
with values that override the default value by specifying
the value for the directly preceding enum name.
**keys is a hack to allow to override the default name (Enum_Repr)
for the dict used to store the reverse mapping from enum
value to enum string"""
# The value of the last added enum
Last_Enum = -1
# the dictionary mapping enumerations to values
Enum_Repr = {}
# an instance of an enumerated type container
New_Enum = __Enum_Class()
# for each argument
for Enum in args:
# if I was passed a string enumeration
if type(Enum) == types.StringType:
# add one element to the enumeration
Last_Enum += 1
# add the value to the enumerated list
New_Enum.__dict__[Enum] = Last_Enum
Enum_Repr[Last_Enum] = Enum
# if not a string, it had better be an integer!
elif type (Enum) != types.IntType:
raise ValueError, "Enumeration must be a string or integer"
# check for a change in the enumeration sequence
elif Enum > Last_Enum:
# change the ordinal value of the last enumeration
New_Enum.__dict__[Enum_Repr[Last_Enum]] = Enum
# move the enumeration to its new position
Enum_Repr[Enum] = Enum_Repr[Last_Enum]
# delete the old position of the enumeration
del Enum_Repr[Last_Enum]
# remember the new value of the end of the enumeration
Last_Enum = Enum
# check if the enumeration change was backward!
elif Enum < Last_Enum:
raise ValueError, "Enumeration value out of bound"
# end if I was passed a string enumeration
# end for each argument
# store the enumeration string in the class' dictionary
New_Enum.__dict__[keys.get(Enum_Repr, "__Enum_Repr")] = Enum_Repr
# return the new enumeration to the caller
return New_Enum
# end def enum
I foolishly wrote:
> Is is possible to modify the 'enum' function so that I don't have to provide a
> class? I would like to use something like this method to create enumerated types,
> but I don't want to keep generating classes that say:
>
> class Ufda:
> def __repr__(self):
> return self.Enum_Repr[self.type]
>
> I would like to just do a:
>
> MIDI_Event = enum("NOTE_ON", "NOTE_OFF", 3, "POLYPHONIC_KEY_PRESSURE",
> "CONTROLLER_CHANGE")
>
> and then do MIDI_Event.NOTE_ON.
>
> On a related note, how would I map between the enumeration and its ordinal value?
> Would I add the methods 'ord' and 'val' to the base class
> (MIDI_Event.ord(MIDI_Event.NOTE_OFF)) yields 3 and MIDI_Event.val(0) yields
> MIDI_Event.NOTE_ON)?
>
> Not being very use to OO and classes, I may need some adult supervision on this ;)
>
> Thanks,
>
> Jonathan Polley
> jwpolley at collins.rockwell.com
>
More information about the Python-list
mailing list