symbian-qemu-0.9.1-12/python-2.6.1/Demo/metaclasses/Enum.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Enumeration metaclass.
       
     2 
       
     3 XXX This is very much a work in progress.
       
     4 
       
     5 """
       
     6 
       
     7 import string
       
     8 
       
     9 class EnumMetaClass:
       
    10     """Metaclass for enumeration.
       
    11 
       
    12     To define your own enumeration, do something like
       
    13 
       
    14     class Color(Enum):
       
    15         red = 1
       
    16         green = 2
       
    17         blue = 3
       
    18 
       
    19     Now, Color.red, Color.green and Color.blue behave totally
       
    20     different: they are enumerated values, not integers.
       
    21 
       
    22     Enumerations cannot be instantiated; however they can be
       
    23     subclassed.
       
    24 
       
    25     """
       
    26 
       
    27     def __init__(self, name, bases, dict):
       
    28         """Constructor -- create an enumeration.
       
    29 
       
    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}.
       
    36 
       
    37         """
       
    38         for base in bases:
       
    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)
       
    42         self.__name__ = name
       
    43         self.__bases__ = bases
       
    44         self.__dict = {}
       
    45         for key, value in dict.items():
       
    46             self.__dict[key] = EnumInstance(name, key, value)
       
    47 
       
    48     def __getattr__(self, name):
       
    49         """Return an enumeration value.
       
    50 
       
    51         For example, Color.red returns the value corresponding to red.
       
    52 
       
    53         XXX Perhaps the values should be created in the constructor?
       
    54 
       
    55         This looks in the class dictionary and if it is not found
       
    56         there asks the base classes.
       
    57 
       
    58         The special attribute __members__ returns the list of names
       
    59         defined in this class (it does not merge in the names defined
       
    60         in base classes).
       
    61 
       
    62         """
       
    63         if name == '__members__':
       
    64             return self.__dict.keys()
       
    65 
       
    66         try:
       
    67             return self.__dict[name]
       
    68         except KeyError:
       
    69             for base in self.__bases__:
       
    70                 try:
       
    71                     return getattr(base, name)
       
    72                 except AttributeError:
       
    73                     continue
       
    74 
       
    75         raise AttributeError, name
       
    76 
       
    77     def __repr__(self):
       
    78         s = self.__name__
       
    79         if self.__bases__:
       
    80             s = s + '(' + string.join(map(lambda x: x.__name__,
       
    81                                           self.__bases__), ", ") + ')'
       
    82         if self.__dict:
       
    83             list = []
       
    84             for key, value in self.__dict.items():
       
    85                 list.append("%s: %s" % (key, int(value)))
       
    86             s = "%s: {%s}" % (s, string.join(list, ", "))
       
    87         return s
       
    88 
       
    89 
       
    90 class EnumInstance:
       
    91     """Class to represent an enumeration value.
       
    92 
       
    93     EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
       
    94     like the integer 12 when compared, but doesn't support arithmetic.
       
    95 
       
    96     XXX Should it record the actual enumeration rather than just its
       
    97     name?
       
    98 
       
    99     """
       
   100 
       
   101     def __init__(self, classname, enumname, value):
       
   102         self.__classname = classname
       
   103         self.__enumname = enumname
       
   104         self.__value = value
       
   105 
       
   106     def __int__(self):
       
   107         return self.__value
       
   108 
       
   109     def __repr__(self):
       
   110         return "EnumInstance(%r, %r, %r)" % (self.__classname,
       
   111                                              self.__enumname,
       
   112                                              self.__value)
       
   113 
       
   114     def __str__(self):
       
   115         return "%s.%s" % (self.__classname, self.__enumname)
       
   116 
       
   117     def __cmp__(self, other):
       
   118         return cmp(self.__value, int(other))
       
   119 
       
   120 
       
   121 # Create the base class for enumerations.
       
   122 # It is an empty enumeration.
       
   123 Enum = EnumMetaClass("Enum", (), {})
       
   124 
       
   125 
       
   126 def _test():
       
   127 
       
   128     class Color(Enum):
       
   129         red = 1
       
   130         green = 2
       
   131         blue = 3
       
   132 
       
   133     print Color.red
       
   134     print dir(Color)
       
   135 
       
   136     print Color.red == Color.red
       
   137     print Color.red == Color.blue
       
   138     print Color.red == 1
       
   139     print Color.red == 2
       
   140 
       
   141     class ExtendedColor(Color):
       
   142         white = 0
       
   143         orange = 4
       
   144         yellow = 5
       
   145         purple = 6
       
   146         black = 7
       
   147 
       
   148     print ExtendedColor.orange
       
   149     print ExtendedColor.red
       
   150 
       
   151     print Color.red == ExtendedColor.red
       
   152 
       
   153     class OtherColor(Enum):
       
   154         white = 4
       
   155         blue = 5
       
   156 
       
   157     class MergedColor(Color, OtherColor):
       
   158         pass
       
   159 
       
   160     print MergedColor.red
       
   161     print MergedColor.white
       
   162 
       
   163     print Color
       
   164     print ExtendedColor
       
   165     print OtherColor
       
   166     print MergedColor
       
   167 
       
   168 if __name__ == '__main__':
       
   169     _test()