1 """Enumeration metaclass.
3 XXX This is very much a work in progress.
10 """Metaclass for enumeration.
12 To define your own enumeration, do something like
19 Now, Color.red, Color.green and Color.blue behave totally
20 different: they are enumerated values, not integers.
22 Enumerations cannot be instantiated; however they can be
27 def __init__(self
, name
, bases
, dict):
28 """Constructor -- create an enumeration.
30 Called at the end of the class statement. The arguments are
31 the name of the new class, a tuple containing the base
32 classes, and a dictionary containing everything that was
33 entered in the class' namespace during execution of the class
34 statement. In the above example, it would be {'red': 1,
35 'green': 2, 'blue': 3}.
39 if base
.__class
__ is not EnumMetaClass
:
40 raise TypeError, "Enumeration base class must be enumeration"
41 bases
= filter(lambda x
: x
is not Enum
, bases
)
43 self
.__bases
__ = bases
45 for key
, value
in dict.items():
46 self
.__dict
[key
] = EnumInstance(name
, key
, value
)
48 def __getattr__(self
, name
):
49 """Return an enumeration value.
51 For example, Color.red returns the value corresponding to red.
53 XXX Perhaps the values should be created in the constructor?
55 This looks in the class dictionary and if it is not found
56 there asks the base classes.
58 The special attribute __members__ returns the list of names
59 defined in this class (it does not merge in the names defined
63 if name
== '__members__':
64 return self
.__dict
.keys()
67 return self
.__dict
[name
]
69 for base
in self
.__bases
__:
71 return getattr(base
, name
)
72 except AttributeError:
75 raise AttributeError, name
80 s
= s
+ '(' + string
.join(map(lambda x
: x
.__name
__,
81 self
.__bases
__), ", ") + ')'
84 for key
, value
in self
.__dict
.items():
85 list.append("%s: %s" % (key
, int(value
)))
86 s
= "%s: {%s}" % (s
, string
.join(list, ", "))
91 """Class to represent an enumeration value.
93 EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
94 like the integer 12 when compared, but doesn't support arithmetic.
96 XXX Should it record the actual enumeration rather than just its
101 def __init__(self
, classname
, enumname
, value
):
102 self
.__classname
= classname
103 self
.__enumname
= enumname
110 return "EnumInstance(%s, %s, %s)" % (`self
.__classname`
,
115 return "%s.%s" % (self
.__classname
, self
.__enumname
)
117 def __cmp__(self
, other
):
118 return cmp(self
.__value
, int(other
))
121 # Create the base class for enumerations.
122 # It is an empty enumeration.
123 Enum
= EnumMetaClass("Enum", (), {})
136 print Color
.red
== Color
.red
137 print Color
.red
== Color
.blue
141 class ExtendedColor(Color
):
148 print ExtendedColor
.orange
149 print ExtendedColor
.red
151 print Color
.red
== ExtendedColor
.red
153 class OtherColor(Enum
):
157 class MergedColor(Color
, OtherColor
):
160 print MergedColor
.red
161 print MergedColor
.white
168 if __name__
== '__main__':