Return two Enum states

Question:

Suppose, I have

class State(Enum):
    TAKEPROFIT  = 1
    STOPPEDOUT  = 2
    WINNER      = 3
    LOSER       = 4

How can I return the combination of e.g. State.STOPPEDOUT and State.LOSER ?
The | does not seem to be supported:

return State.STOPPEDOUT | State.LOSER

throws

TypeError: unsupported operand type(s) for |: 'State' and 'State'
Asked By: Jan

||

Answers:

Use an IntEnum instead of an Enum:

from enum import IntEnum


class State(IntEnum):
    TAKEPROFIT = 1
    STOPPEDOUT = 2
    WINNER = 3
    LOSER = 4

An IntEnum behaves like an int, so:

>>> State.STOPPEDOUT | State.LOSER
6
Answered By: larsks

Enums have a value attribute:

class State(Enum):
    TAKEPROFIT  = 1
    STOPPEDOUT  = 2
    WINNER      = 3
    LOSER       = 4

State.STOPPEDOUT.value | State.LOSER.value # 6
Answered By: Daniel Viglione

While the answer by @larsks is correct, the "more" correct way to do so would be inheriting from IntFlag (auto() generates powers of 2; you can use your own values if you so choose):

from enum import IntFlag, auto

class State(IntFlag):
  TAKEPROFIT = auto()
  STOPPEDOUT = auto()
  WINNER = auto()
  LOSER = auto()

|, & and ^ operations result in instances of the same class:

>>> State.STOPPEDOUT | State.LOSER
<State.STOPPEDOUT|LOSER: 10>
>>> State.STOPPEDOUT & State.LOSER
<State: 0>
>>> State.STOPPEDOUT ^ (State.LOSER | State.STOPPEDOUT | State.TAKEPROFIT)
<State.TAKEPROFIT|LOSER: 9>

in operations are also supported:

>>> State.STOPPEDOUT in (State.STOPPEDOUT | State.LOSER)
True

IntFlag is a subclass of int and Flag (which is inturn a subclass of Enum), and therefore its instances can be used anywhere an int is expected:

>>> State.WINNER + 9
13

Note that if an IntFlag is inverted, it returns an union of the rest of the flags instead:

>>> ~State.TAKEPROFIT
<State.STOPPEDOUT|WINNER|LOSER: 14>
Answered By: InSync
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.