Equivalent to C bitmasks and enumerations

Scott David Daniels Scott.Daniels at Acm.Org
Wed Apr 15 15:42:53 EDT 2009


Ulrich Eckhardt wrote:
> Greetings!
> 
> I'm currently using Python to implement a set of tests for code that is
> otherwise written in C. This code was wrapped using Boost.Python and is
> then loaded into Python as module.
> 
> What I often have in C is this:
> 
>   // bitfield (several flags combined)
>   #define STATUS_OVERTEMP 1u
>   #define STATUS_ON_FIRE 2u
>   #define STATUS_BORED 4u
>   unsigned get_status(void);
> 
>   // enumeration (distinct values from a set)
>   enum color { color_red=1, color_green=13, color_mauve=42 };
>   enum color get_color(void);
> 
> What I'm looking for is a suggestion how to handle this in Python. Note that
> technically, this works without problem, I'm rather looking for stylistic
> advise. What I currently have is these (note: I'm retyping this, so ignore
> any syntax errors, please):
> 
>  STATUS_OVERTEMP = 1
>  STATUS_ON_FIRE = 2
>  STATUS_BORED = 4
>  def status_as_string(st):
>      tmp = []
>      if st&STATUS_OVERTEMP:
>          tmp.append("OVERTEMP")
>      if st&STATUS_ON_FIRE:
>          tmp.append("ON_FIRE")
>      if st&STATUS_BORED:
>          tmp.append("BORED")
>      return "|".join(tmp)
> 
>  COLOR_RED = 1
>  COLOR_GREEN = 13
>  COLOR_MAUVE = 42
>  def color_as_string(c):
>      names = {
>          COLOR_RED:"RED",
>          COLOR_GREEN:"GREEN",
>          COLOR_MAUVE:"MAUVE"}
>      return names[c];
> 
> Further, I also tried defining a separate class:
> 
>  class Color(int):
>      RED = 1
>      GREEN = 13
>      MAUVE = 42
>      names = { RED:"RED", GREEN:"GREEN", MAUVE:"MAUVE"}
> 
>      def __str__(self):
>          return names[c];
>      ...
>   
> 
> To be a bit more explicit about what I would like, here is an example how I
> would like to use it:
> 
>   c = Color.RED
>   type(c) # should yield class Color
>   str(c) # should yield "RED"
>   Color(999) # should signal the invalid color value
> 
> 
> Any other suggestions how to structure this or rewrite this?
> 
> thanks!
> 
> Uli
> 
>   
Here's a hack:

     class Status(int):
         _bits = [('OVERTEMP', 1), ('ON_FIRE', 2), ('BORED', 4)]

         def __repr__(self):
             parts = []
             v = int(self)
             for name, value in self._bits:
                 if v & value:
                     parts.append(name)
                     v ^= value
             if v or not parts:
                 parts.append(hex(v))
             return '%s(%s)' % (self.__class__.__name__,
                                '|'.join(parts))
     for _name, _value in Status._bits:
         setattr(Status, _name, Status(_value))


--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list