Reputation: 97
as newbie to python and hex based enums, I'm trying to wrap my head around something. My scenario is that I have a device that is sending me flags and I'm trying to determine which flags are set. I'm using python 3.7.
I've play around with the Python enum(Flag) class and can't seem to get it working. In the example below, I simulated a response of a status of "Running" and on "External Power".
from enum import Flag
class device_flags(Flag):
RUNNING = (0x00000001)
STOPPED = (0x00000004)
PAUSED = (0x00000200)
BAT_POWER = (0x01000000)
EXT_POWER = (0x10000000)
device_status_flag = (0x10000001) # simulate a response from device
print(device_status_flag in device_flags)
for flag in device_flags:
print('{:15} = {}'.format(flag.name, device_status_flag in flag))
From what I've read, I would expect this to return true but I'm getting false(s):
(run results...)
False
RUNNING = False
STOPPED = False
PAUSED = False
BAT_POWER = False
EXT_POWER = False
Does someone explain where I've gone wrong? (
I'm also getting a Deprecation Warning
"using non-Enums in containment checks will raise TypeError in Python 3.8"
--- How should I be comparing this?
Upvotes: 2
Views: 2232
Reputation: 10799
If you're strictly working with Flag objects, something like this:
def main():
from enum import Flag
class DeviceFlag(Flag):
Running = 0x1
Stopped = 0x2
ExternalPower = 0x4
input_status = DeviceFlag.Running | DeviceFlag.ExternalPower
for flag in DeviceFlag:
name = flag.name
is_set = bool(flag & input_status)
print(f"{name}: {is_set}")
return 0
if __name__ == "__main__":
from sys import exit
exit(main())
Output:
Running: True
Stopped: False
ExternalPower: True
However, it sounds like you really do need to work with integers (hex values) since your flags are coming from an external device. In that case you'll have to use an IntFlag instead (an IntFlag inherits from int
which allows you to compare it with integers):
def main():
from enum import IntFlag
class DeviceFlag(IntFlag):
Running = 0x1
Stopped = 0x2
ExternalPower = 0x4
# input_status = 0x5
input_status = 0b101
for flag in DeviceFlag:
name = flag.name
is_set = bool(flag & input_status)
print(f"{name}: {is_set}")
return 0
if __name__ == "__main__":
from sys import exit
exit(main())
Upvotes: 4