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