new enum idiom

Carel Fellinger cfelling at iae.nl
Sat Jan 6 21:18:57 EST 2001


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