new enum idiom

Jonathan Polley
Sun Jan 7 13:47:29 EST 2001


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


Carel Fellinger wrote:

> Will Ware <wware at world.std.com> wrote:
> ...
> > and I would have used this except that I had too many values to count
> > conveniently. Also I wanted to keep around string versions of the enum
> > names, for __repr__ purposes. So I hit upon this idiom:
>
> > class MidiEvent:
>
> >     typeNames = [
> >         "NOTE_ON", "NOTE_OFF", "POLYPHONIC_KEY_PRESSURE", "CONTROLLER_CHANGE",
> >         # dozens and dozens more...
> >         ]
>
> >     # build an enum, this is done once when the module is imported
> >     # locals() gives the namespace for this class, so they become
> >     # class attributes
>
> According to the docs locals() returns dicts that are ment to be
> read-only:( So you'll have to spell it out.  Unfortunately __dict__ is
> unnown at this moment, so is MidiEvent.  Simply postpone it till after
> the class definition of MidiEvent is finished.
>
> Classs MidiEvent:
>     typeNames = ["NOTE_ON", "NOTE_OFF", "...
>
> i = 0
> for t in MidiEvent.typeNames:
>     MidiEvent.__dict__[t] = i
>
> And inspired by Alex's recent contribution for parsing possibly
> `valued' command-line like options you could easily enhance this
> enumeration idiom to deal with things as enum (a, b=2, c, d=4).
>
> def enum(C, *args, **keys):
>     '''Create and enumerate to your hearts delight,
>        C is the class that wants enumerations,
>        *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 (enumRepr)
>           for the dict used to store the reverse mapping from enum
>           value to enum string
>     '''
>     i, enumRepr = -1, {}   # i is the value of the last added enum
>     for x in args:
>         if type(x) == type(""):
>             i += 1
>             C.__dict__[x], enumRepr[i] = i, x
>         elif x>i:
>             C.__dict__[enumRepr[i]], enumRepr[x] = x, enumRepr[i]
>             del enumRepr[i]
>             i = x
>         elif x<i:
>             raise ValueError, "Enumeration value out of bound"
>     C.__dict__[keys.get(enumRepr, "enumRepr")] = enumRepr
>
> Class MidiEvent:
>
>     def __repr__(self):
>         r = ("<MidiEvent %s blah blah blah" %
>              (self.enumRepr[self.type], blah, blah, blah))
>         # other info
>         return r + ">"
>
> enum(MidiEvent,
>      "NOTE_ON", "NOTE_OFF", 3, "POLYPHONIC_KEY_PRESSURE", "CONTROLLER_CHANGE")
>
> > --
> > import string,time,os;print string.join((lambda x:x[:10]+x[8:])(map(
> > lambda x:string.center("*"*(lambda x:((x<24) ### Seasons Greetings, Will Ware
> > *(x-3))+3)(x),24),range(1,28, 2))),"\n") ################ wware at world.std.com
>
> And the best wishes to you too.  (you know that in Holland the sixth
> of jan. is taken to be the day that your christmas tree has to vanish:)
> --
> groetjes, carel




More information about the Python-list mailing list