1
"""Enumeration metaclass."""
3
class EnumMetaclass(type):
4
"""Metaclass for enumeration.
6
To define your own enumeration, do something like
13
Now, Color.red, Color.green and Color.blue behave totally
14
different: they are enumerated values, not integers.
16
Enumerations cannot be instantiated; however they can be
20
def __init__(cls, name, bases, dict):
21
super(EnumMetaclass, cls).__init__(name, bases, dict)
23
for attr in dict.keys():
24
if not (attr.startswith('__') and attr.endswith('__')):
25
enumval = EnumInstance(name, attr, dict[attr])
26
setattr(cls, attr, enumval)
27
cls._members.append(attr)
29
def __getattr__(cls, name):
30
if name == "__members__":
32
raise AttributeError, name
36
enumbases = [base.__name__ for base in cls.__bases__
37
if isinstance(base, EnumMetaclass) and not base is Enum]
39
s1 = "(%s)" % ", ".join(enumbases)
40
enumvalues = ["%s: %d" % (val, getattr(cls, val))
41
for val in cls._members]
43
s2 = ": {%s}" % ", ".join(enumvalues)
44
return "%s%s%s" % (cls.__name__, s1, s2)
46
class FullEnumMetaclass(EnumMetaclass):
47
"""Metaclass for full enumerations.
49
A full enumeration displays all the values defined in base classes.
52
def __init__(cls, name, bases, dict):
53
super(FullEnumMetaclass, cls).__init__(name, bases, dict)
54
for obj in cls.__mro__:
55
if isinstance(obj, EnumMetaclass):
56
for attr in obj._members:
58
if not attr in cls._members:
59
cls._members.append(attr)
61
class EnumInstance(int):
62
"""Class to represent an enumeration value.
64
EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
65
like the integer 12 when compared, but doesn't support arithmetic.
67
XXX Should it record the actual enumeration rather than just its
71
def __new__(cls, classname, enumname, value):
72
return int.__new__(cls, value)
74
def __init__(self, classname, enumname, value):
75
self.__classname = classname
76
self.__enumname = enumname
79
return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname,
83
return "%s.%s" % (self.__classname, self.__enumname)
86
__metaclass__ = EnumMetaclass
89
__metaclass__ = FullEnumMetaclass
100
print repr(Color.red)
101
print Color.red == Color.red
102
print Color.red == Color.blue
106
class ExtendedColor(Color):
113
print ExtendedColor.orange
114
print ExtendedColor.red
116
print Color.red == ExtendedColor.red
118
class OtherColor(Enum):
122
class MergedColor(Color, OtherColor):
125
print MergedColor.red
126
print MergedColor.white
135
class Color(FullEnum):
142
print repr(Color.red)
143
print Color.red == Color.red
144
print Color.red == Color.blue
148
class ExtendedColor(Color):
155
print ExtendedColor.orange
156
print ExtendedColor.red
158
print Color.red == ExtendedColor.red
160
class OtherColor(FullEnum):
164
class MergedColor(Color, OtherColor):
167
print MergedColor.red
168
print MergedColor.white
175
if __name__ == '__main__':