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__':