new enum idiom

Patricia Hawkins phawkins at connact.com
Sat Jan 13 13:23:12 EST 2001


>>>>> "JD" == Jan Dries <jan.dries at dcube-resource.be> writes:

JD> I once wrote a class to simulate enums. Using it, you can write:

JD>   colors = enum("GREEN","BLUE","RED","YELLOW")

JD> and you can subsequently refer to the enum constants as:
  
JD>   x = colors.GREEN

JD> If no value is supplied, the first name is assigned 0, the second 1 and
JD> so on. But you can supply values, as in:

JD>   colors = enum("GREEN=1","BLUE=0x08","RED","YELLOW")

Well, that implements most of _this_ thread, right there.  

I'd put off studying __setattr__ -- thanks, that's a nice example of
how to use it to prevent unwanted access.

Hope you don't mind, but in the course of playing with it, I added
type checking, improved the exception handling, and allowed split to
only split once, so that "PURPLE=3=4=5" will be a syntax error --
code, like cats, should barf easily, and without much distress.
 
Of course, you can still say:
        colors = enum("1=64", "GREEN=1","BLUE=0x08","RED","YELLOW")
but if the language allows it, who am I to disallow it?

#  Jan Dries <jan.dries at dcube-resource.be>
#  To: python-list at python.org
#  Date: Sun, 07 Jan 2001 22:09:22 +0100
#  Organization: D-Cube Resource
#
#
# PJH -- 1/13/2001
#        *Added type check -> raise TypeError.
#        *substitued AccessError for AttributeError,
#         so as to report the exact crime.
#        *Added maxsplit argument to split, now eval will check syntax
#         for us.
#

import exceptions
from types import *
import re

class enum:
    def __init__(self,*names):
        self.__mnames = {}
        value = 0;

        for i in names:
            pairs = re.split("\s*[=]\s*",i, 1)
            if len(pairs) == 2:
                value = eval(pairs[1])
            if type(value) not in (IntType, LongType):
                    raise TypeError, "Non-integer type %s: %s"%(type(value),str(value))
                
            self.__mnames[pairs[0]] = value
            value += 1
			
    def __getattr__(self,name):
        try:
            return self.__mnames[name]
        except:
            raise AttributeError
			
    def __setattr__(self,name,value):
        if name == "_enum__mnames":
            self.__dict__[name] = value
        else:
            raise AccessError, "You may not change %s.%s "%(self, name)

class AccessError(exceptions.Exception):
    pass






More information about the Python-list mailing list