How to use bitwise flags in Python
Question:
from enum import Enum
class InputTypes(Enum):
"""
Flags to represent the different kinds of input we
are acting on from the user
"""
KEYBOARD = 0b00000001,
MOUSE_BUTTONS = 0b00000010,
MOUSE_MOVE = 0b00000100,
ALL = 0b11111111
if __name__ == "__main__":
x = (InputTypes.KEYBOARD | InputTypes.MOUSE_BUTTONS)
I am getting an error:
TypeError: unsupported operand type(s) for |: 'InputTypes' and 'InputTypes'
How do I properly define some flags and use them, in python 2.7 and in python3?
Answers:
Instead of using the basic Enum
, you could use an IntFlag
:
from enum import IntFlag
class InputTypes(IntFlag):
# Rest of your code
The Enum base class overrides class variable access to make them return an instance of the subclass itself. If you don’t subclass Enum (and remove the commas), your code will not crash.
Note that you can use sets of Enum entries instead of bit maps to obtain the same result using InputTypes(Enum)
For Python 2 you want to use aenum
(Advanced Enum)1. If the numeric values are not important you can use Flag
:
from aenum import Flag, auto
class InputTypes(Flag):
"""
Flags to represent the different kinds of input we
are acting on from the user
"""
KEYBOARD = auto()
MOUSE_BUTTONS = auto()
MOUSE_MOVE = auto()
ALL = KEYBOARD | MOUSE_BUTTONS | MOUSE_MOVE
If the values are important (meaning you’ll be using them as integers), then use IntFlag
instead.
1 Disclosure: I am the author of the Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.
from enum import Enum
class InputTypes(Enum):
"""
Flags to represent the different kinds of input we
are acting on from the user
"""
KEYBOARD = 0b00000001,
MOUSE_BUTTONS = 0b00000010,
MOUSE_MOVE = 0b00000100,
ALL = 0b11111111
if __name__ == "__main__":
x = (InputTypes.KEYBOARD | InputTypes.MOUSE_BUTTONS)
I am getting an error:
TypeError: unsupported operand type(s) for |: 'InputTypes' and 'InputTypes'
How do I properly define some flags and use them, in python 2.7 and in python3?
Instead of using the basic Enum
, you could use an IntFlag
:
from enum import IntFlag
class InputTypes(IntFlag):
# Rest of your code
The Enum base class overrides class variable access to make them return an instance of the subclass itself. If you don’t subclass Enum (and remove the commas), your code will not crash.
Note that you can use sets of Enum entries instead of bit maps to obtain the same result using InputTypes(Enum)
For Python 2 you want to use aenum
(Advanced Enum)1. If the numeric values are not important you can use Flag
:
from aenum import Flag, auto
class InputTypes(Flag):
"""
Flags to represent the different kinds of input we
are acting on from the user
"""
KEYBOARD = auto()
MOUSE_BUTTONS = auto()
MOUSE_MOVE = auto()
ALL = KEYBOARD | MOUSE_BUTTONS | MOUSE_MOVE
If the values are important (meaning you’ll be using them as integers), then use IntFlag
instead.
1 Disclosure: I am the author of the Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.