Python enums revisited

Will Ware wware at world.std.com
Thu Aug 23 05:41:00 CEST 2001


""" I once tried to give Python something like C's enums, as
described here:
http://groups.google.com/groups?selm=G6qzLy.6Fo%40world.std.com
That approach had the flaw of trying to assign to a dictionary
returned by the locals() function, intending that such assignments
would become class attributes, but that isn't guaranteed to work
in future versions of Python. The present line of thinking was
prompted by the "name-->method lookup" thread.
"""

import types, string, pprint

def attachEnums(clas, enumList):
    i = 0
    for x in enumList:
        if type(x) == types.TupleType:
            x, i = x
        assert type(x) == types.StringType
        assert type(i) == types.IntType  # allow longs???
        setattr(clas, x, i)
        try: clas.enumNames[i] = x
        except AttributeError: clas.enumNames = {i: x}
        i = i + 1

class MidiEvent:
    """MidiEvent is a class"""
    def __repr__(self):
        # It's handy to be able to reverse-lookup the names of the
        # enum values. C doesn't offer this feature.
        return ("<MidiEvent %s>" %
                (self.enumNames[self.type]))


attachEnums(MidiEvent,
            ["NOTE_ON",
             "NOTE_OFF",
             "ANOTHER_MIDI_EVENT",
             "SOME_OTHER_MIDI_EVENT",
             ("CONTROLLER_CHANGE", 500),
             ("POLYPHONIC_KEY_PRESSURE", 271828),
             # many many more...
             ])

for x in string.split(
"""
m = MidiEvent()   # MidiEvent is a class, m is an instance
m.type = MidiEvent.POLYPHONIC_KEY_PRESSURE
print m

# Notice that m's attributes include neither the enums themselves nor
# the enumNames dictionary. These are CLASS attributes, not INSTANCE
# attributes, and that means you can create vast numbers of MidiEvent
# instances with reckless abandon, never worrying that namespaces and
# memory will become cluttered with redundant copies of your enums.
pprint.pprint(MidiEvent.__dict__)
print m.__dict__
""", "\n"):
    if x and x[:1] != '#':
        print ">>>", x
        exec x
    else:
        print x

-- 
-----------------------------------+---------------------
 22nd century: Esperanto, geodesic | Will Ware
 domes, hovercrafts, metric system | wware at world.std.com



More information about the Python-list mailing list