The Python Oracle

Flag usage for multibranch logic

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Mysterious Puzzle

--

Chapters
00:00 Question
01:17 Accepted answer (Score 2)
01:42 Answer 2 (Score 4)
02:55 Thank you

--

Full question
https://stackoverflow.com/questions/5753...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #enums #flags

#avk47



ANSWER 1

Score 4


Note: See Ethan Furman's answer for the proper Pythonic approach to this problem. This answer explains how to check for flag inclusion with bitwise operators, which are useful in other situations and other programming languages.

To check for flag inclusion in a value, you should use bitwise operators, specifically &.

wiseness = WISENESS.MD
if wiseness & WISENESS.Y == WISENESS.Y:
    print('contains Y')
if wiseness & WISENESS.M == WISENESS.M:
    print('contains M')
if wiseness & WISENESS.D == WISENESS.D:
    print('contains D')

The & AND operator works by returning which bits are the same in the two supplied values. In your enum definition, auto() supplies the values Y = 1, M = 2, D = 4, which in binary are 0001, 0010, and 0100 respectively. The combination values then contain a bit from each flag they contain, formed by the | OR operator, for example MD = 0010 | 0100 = 0110.

In the above code then, where wiseness is 0110, the following & checks are made:

wiseness & WISENESS.Y --> 0110 & 0001 = 0000 --> != WISENESS.Y
wiseness & WISENESS.M --> 0110 & 0010 = 0010 --> == WISENESS.M
wiseness & WISENESS.D --> 0110 & 0100 = 0100 --> == WISENESS.D



ACCEPTED ANSWER

Score 2


The built-in way to check for Flag membership is with the standard Python in operator:

>>> second_case in WISENESS.Y
True

and your final example would be:

some_flag = ...

if WISENESS.Y in some_flag:
    do_something_in_case_of_Y_or_MY_or_YD_or_YMD()
if WISENESS.M in some flag:
    do_something_in_case_of_M_or_MD_or_YM_or_YMD()
if WISENESS.D in some flag:
    do_something_in_case_of_D_or_MD_or_YD_or_YMD()