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 | ww...@world.std.com
import types, string, pprint, exceptions
class EnumException(exceptions.Exception):
pass
def attachEnums(clas, enumList):
i = 0
uniqueValues = [ ]
for x in enumList:
if type(x) == types.TupleType:
x, i = x
if type(x) != types.StringType:
raise EnumException, \
"enum name is not a string: " + x
if type(i) != types.IntType:
raise EnumException, \
"enum value is not an integer: " + i
if i in uniqueValues:
raise EnumException, \
"enum value is not unique for " + x
uniqueValues.append(i)
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", 500),
import types, string, pprint, exceptions
class EnumException(exceptions.Exception):
pass
class Enumeration:
def __init__(self, name, enumList):
self.__doc__ = name
lookup = { }
reverseLookup = { }
i = 0
uniqueNames = [ ]
uniqueValues = [ ]
for x in enumList:
if type(x) == types.TupleType:
x, i = x
if type(x) != types.StringType:
raise EnumException, "enum name is not a string: " + x
if type(i) != types.IntType:
raise EnumException, "enum value is not an integer: " + i
if x in uniqueNames:
raise EnumException, "enum name is not unique: " + x
if i in uniqueValues:
raise EnumException, "enum value is not unique for " + x
uniqueNames.append(x)
uniqueValues.append(i)
lookup[x] = i
reverseLookup[i] = x
i = i + 1
self.lookup = lookup
self.reverseLookup = reverseLookup
def __getattr__(self, attr):
if not self.lookup.has_key(attr):
raise AttributeError
return self.lookup[attr]
def whatis(self, value):
return self.reverseLookup[value]
Volkswagen = Enumeration("Volkswagen",
["JETTA",
"RABBIT",
"BEETLE",
("THING", 400),
"PASSAT",
"GOLF",
("CABRIO", 700),
"EURO_VAN",
"CLASSIC_BEETLE",
"CLASSIC_VAN"
])
Insect = Enumeration("Insect",
["ANT",
"APHID",
"BEE",
"BEETLE",
"BUTTERFLY",
"MOTH",
"HOUSEFLY",
"WASP",
"CICADA",
"GRASSHOPPER",
"COCKROACH",
"DRAGONFLY"
])
def demo(lines):
previousLineEmpty = 0
for x in string.split(lines, "\n"):
if x:
if x[0] != '#':
print ">>>", x; exec x; print
previousLineEmpty = 1
else:
print x
previousLineEmpty = 0
elif not previousLineEmpty:
print x
previousLineEmpty = 1
def whatkind(value, enum):
return enum.__doc__ + "." + enum.whatis(value)
class ThingWithType:
def __init__(self, type):
self.type = type
demo("""
car = ThingWithType(Volkswagen.BEETLE)
print whatkind(car.type, Volkswagen)
bug = ThingWithType(Insect.BEETLE)
print whatkind(bug.type, Insect)
# Notice that car's and bug's attributes don't include any of the
# enum machinery, because that machinery is all CLASS attributes and
# not INSTANCE attributes. So you can generate thousands of cars and
# bugs with reckless abandon, never worrying that time or memory will
# be wasted on redundant copies of the enum stuff.
print car.__dict__
print bug.__dict__
pprint.pprint(Volkswagen.__dict__)
pprint.pprint(Insect.__dict__)
""")