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'
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
Enums have a value attribute:
class State(Enum):
TAKEPROFIT = 1
STOPPEDOUT = 2
WINNER = 3
LOSER = 4
State.STOPPEDOUT.value | State.LOSER.value # 6
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>
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'
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
Enums have a value attribute:
class State(Enum):
TAKEPROFIT = 1
STOPPEDOUT = 2
WINNER = 3
LOSER = 4
State.STOPPEDOUT.value | State.LOSER.value # 6
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>