Use a dict of key, values. Where key is the incoming state, and the value is the outgoing state. This is a highly Pythonic pattern and one you will likely reuse again and again. In many cases you will want to dispatch on the input state, where you should put functions as values in the dict.
recs = { 'SELL': 1, 'UNDERWEIGHT': 2, 'HOLD': 3, 'OVERWEIGHT': 4, 'BUY': 5, } # this will fail correctly with a KeyError for non - expected states. recommendation = recs[avg_recommendation]
With enum34
:
>>> import enum
>>> class Recommendation(enum.IntEnum):
... BUY = 5
... OVERWEIGHT = 4
... HOLD = 3
... UNDERWEIGHT = 2
... SELL = 1
>>> Recommendation.BUY
<Recommendation.BUY: 5>
>>> Recommendation.BUY.value
5
>>> Recommendation(5)
<Recommendation.BUY: 5>
>>> recs = [Recommendation.BUY, Recommendation.HOLD, Recommendation.BUY]
>>> avg_rec = sum(recs)//len(rec)
>>> Recommendation(rec)
<Recommendation.OVERWEIGHT: 4>
Meanwhile, what if you have a string, like 'HOLD'
, and you want to get a Recommendation.HOLD
out of that? Unfortunately, that's one of the features that was intentionally left out of the stdlib enum
module to keep it simple.* (Read PEP 435 for a full discussion of all of the possible features that were left out and why.) So, if you try it, you'll get an error:
>>> Recommendation('HOLD')
ValueError: HOLD is not a valid Recommendation
But you could use one of the many other enum modules on PyPI. In particular, flufl.enum
** works exactly like the stdlib in all the examples shown above, but also has a few extra features. So, if you pip install flufl.enum
, then change the import enum
to from flufl import enum
, all of the above will work, and so will this:
>>> Recommendation('HOLD')
<EnumValue: Recommendation.HOLD [value=3]>
Functional Programming HOWTO,Enum classes with methods
>>> from enum
import Enum
>>>
class Weekday(Enum):
...MONDAY = 1
...TUESDAY = 2
...WEDNESDAY = 3
...THURSDAY = 4
...FRIDAY = 5
...SATURDAY = 6
...SUNDAY = 7
>>> from enum
import Enum
>>>
class Color(Enum):
...RED = 1
...GREEN = 2
...BLUE = 3
>>> Weekday(3)
<Weekday.WEDNESDAY: 3>
>>> print(Weekday.THURSDAY) Weekday.THURSDAY
>>> type(Weekday.MONDAY)
<enum 'Weekday'>
>>> isinstance(Weekday.FRIDAY, Weekday)
True
>>> print(Weekday.TUESDAY.name) TUESDAY
Last Updated : 16 Aug, 2022
Output:
Season.SPRING
SPRING
1
<enum 'Season'>
<Season.SPRING: 1>
[<Season.SPRING: 1>, <Season.SUMMER: 2>, <Season.AUTUMN: 3>, <Season.WINTER: 4>]
Output:
Enum is hashed
last modified August 5, 2022
#!/usr/bin/python
from enum
import Enum
class Season(Enum):
SPRING = 1
SUMMER = 2
AUTUMN = 3
WINTER = 4
seas = Season.SPRING
print(seas)
if seas == Season.SPRING:
print("Spring")
print(list(Season))
In the example, we have a Season
enumeration which has
four distinct values: SPRING, SUMMER, AUTUMN, and WINTER. To access a member,
we specify the enumeration name followed by a dot and the member name.
class Season(Enum):
SPRING = 1
SUMMER = 2
AUTUMN = 3
WINTER = 4
The Season
enumeration is created with the class
keyword.
We inherit from the enum.Enum
base class. We explicity set numbers
to the enumeration values.
seas = Season.SPRING print(seas)
The Season.SPRING
is used in an if expression.
print(list(Season))
With the list
built-in function, we get the list of all possible values
for the Season
enum.
$ ./simple.py
Season.SPRING
Spring
[<Season.SPRING: 1>, <Season.SUMMER: 2>, <Season.AUTUMN: 3>, <Season.WINTER: 4>]
In this article, you will learn what enums are and how to create and work with them. Furthermore, you will learn why you should use them more often in your day to day coding.,At this point, we have an understanding of what enums are and how we can create them in Python. Furthermore, we are able to compare and work with them. However, we still do not know why we need and should use enumerations more often.,In essence, if you have magic numbers in your code, you should definitely consider to either assign them to a variable or group them together to an enumeration. This way your code's readability increases a lot. It is especially true if you want to write tests for your code.,Note: Although the class syntax is used to define new enumerations, they aren't normal Python classes. If you want to know more about it, check out the How are Enums different? section in the module's documentation [1]:
The following code snippet shows you a simple example of an enum Colour
:
# colour.py
from enum
import Enum
class Colour(Enum):
RED = 1
GREEN = 2
BLUE = 3
Let's see how enums behave when used.
# previous colour.py code c = Colour.RED print(c) print(c.name) print(c.value) print(c is Colour.RED) print(c is Colour.BLUE)
We extended the colour.py
script by creating a new instance of Colour.RED
and assigning it to the variable c
.
Furthermore, we print the string representation of Colour.RED
, its name and value.
Additionally, we compare c
's identity with Colour.RED
and Colour.BLUE
.
$ python colour.py Colour.RED RED 1 True False
# iterate.py
from enum import Enum
class Colour(Enum):
RED = 1
GREEN = 2
BLUE = 3
for name, member in Colour.__members__.items():
print(name, member)
$ python iterate.py RED Colour.RED GREEN Colour.GREEN BLUE Colour.BLUE
You might ask yourself why we did not something like:
for member in Colour:
print(member.name, member)
Enumerations have a special attribute called __members__
, which is a read-only ordered mapping of names and members.
Utilising __members__
allows you to iterate over an enum and print the members as well as their corresponding names.
# iterate.py
from enum
import Enum
class Colour(Enum):
RED = 1
GREEN = 2
BLUE = 3
for name, member in Colour.__members__.items():
print(name, member)
# iterate.py
from enum import Enum
class Colour(Enum):
RED = 1
GREEN = 2
BLUE = 3
for name, member in Colour.__members__.items():
print(name, member)
$ python iterate.py RED Colour.RED GREEN Colour.GREEN BLUE Colour.BLUE
You might ask yourself why we did not something like:
for member in Colour:
print(member.name, member)
In the previous example, we assigned integers to the symbolic names RED
, GREEN
, and BLUE
.
If the exact values are not important, you can use the enum.auto()
function.
The function calls _generate_next_value_()
internally and generates the values for you.
# auto.py
from enum
import auto
from enum
import Enum
class Colour(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
c = Colour.RED
print(c.value)
It chooses a suited value for each enum member, which will (most of the time) be the integers we used before.
$ python auto.py 1
$ python overwritte_next_values.py 2 4 8
Being Python classes, enums can have any (special) methods just like all other classes. Consider the following example.
# extending.py
from enum
import Enum
class Colour(Enum):
RED = 1
GREEN = 2
BLUE = 3
def __str__(self):
return self.name
def colorize(self):
return f "Let's paint everything in {self.name.lower()}"
c = Colour.RED
print(c)
print(c.colorize())
We extended the Colour
enum by a new method colorize()
printing a string generated based on the member's value.
Furthermore, we overwrite the __str__()
dunder method to return the member's name if called.
$ python extending.py RED Let 's paint everything in red
We already know that we can compare enum members using Python's identity operator.
However, the Enum
class does not provide ordered comparisons even though integers are used as values for the enumeration members.
Let's have a look at the following example.
# comparison.py
from enum
import Enum
class Colour(Enum):
RED = 1
GREEN = 2
BLUE = 3
r = Colour.RED
b = Colour.GREEN
print(r < b)
Executing the script at hand results in a TypeError
.
$ python comparison.py
Traceback (most recent call last):
File "/home/florian/workspace/python/why-you-should-use-more-enums-in-python-article-snippets/comparison.py", line 14, in <module>
print(r < b) TypeError: '<' not supported between instances of 'Colour' and 'Colour'
However, the derived enumeration IntEnum
does provide ordered comparisons as it is also a subclass of int
.
In order to make our example work, we need to import the IntEnum
class instead of Enum
and derive Colour
from it.
We do not need to change anything else.
# comparison.py
from enum
import IntEnum
class Colour(IntEnum):
...
If we have a user, who should have read and write permissions for a certain file, we can combine both using the |
operator.
# permissions.py
from enum
import IntFlag
class Permission(IntFlag):
R = 4
W = 2
X = 1
RW = Permission.R | Permission.W
print(RW)
print(Permission.R + Permission.W)
print(Permission.R in RW)
$ python permissions.py Permissions.R | W 6 True
Python is the main dynamic language used at Google. This style guide is a list of dos and don’ts for Python programs.,Never use spaces around = when passing keyword arguments or defining a default parameter value, with one exception: when a type annotation is present, do use spaces around the = for the default parameter value.,Default arguments are evaluated once at module load time. This may cause problems if the argument is a mutable object such as a list or a dictionary. If the function modifies the object (e.g., by appending an item to a list), the default value is modified.,Simpler code, because the state of local variables and control flow are preserved for each call. A generator uses less memory than a function that creates an entire list of values at once.
dict = 'something awful' # Bad Idea...pylint: disable = redefined - builtin
pylint--list - msgs
pylint--help - msg = C6409
def viking_cafe_order(spam: str, beans: str, eggs: Optional[str] = None) - > str: del beans, eggs # Unused by vikings. return spam + spam + spam
from sound.effects
import echo
...
echo.EchoFilter(input, output, delay = 0.7, atten = 4)
Yes:
# Reference absl.flags in code with the complete name(verbose).
import absl.flags
from doctor.who
import jodie
_FOO = absl.flags.DEFINE_string(...)
I know I can hand craft a series of if-statements to do the conversion but is there an easy pythonic way to convert? Basically, I'd like a function ConvertIntToFruit(int) that returns an enum value.,From the Programmatic access to enumeration members and their attributes section of the documentation:,Given the following definition, how can I convert an int to the corresponding Enum value?,My use case is I have a csv file of records where I'm reading each record into an object. One of the file fields is an integer field that represents an enumeration. As I'm populating the object I'd like to convert that integer field from the file into the corresponding Enum value in the object.
Given the following definition, how can I convert an int to the corresponding Enum value?
from enum
import Enum
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
You 'call' the Enum
class:
Fruit(5)
to turn 5
into Fruit.Orange
:
>>> from enum import Enum
>>> class Fruit(Enum):
... Apple = 4
... Orange = 5
... Pear = 6
...
>>> Fruit(5)
<Fruit.Orange: 5>
Sometimes it’s useful to access members in enumerations
programmatically (i.e. situations where Color.red
won’t do because the
exact color is not known at program-writing time). Enum
allows such
access:
>>> Color(1)
<Color.red: 1>
>>> Color(3)
<Color.blue: 3>
Sometimes it’s useful to access members in enumerations
programmatically (i.e. situations where Color.red
won’t do because the
exact color is not known at program-writing time). Enum
allows such
access:
>>> Color(1)
<Color.red: 1>
>>> Color(3)
<Color.blue: 3>