Picture by Creator
For those who’ve programmed in a language like C++ or Java, you’ve doubtless used enums to create named constants. Enums are useful when you’ve gotten a variable that takes one among a set variety of values—typically associated equivalent to the times of the week, pupil grades, order standing, and the like.
Python, nevertheless, doesn’t have an express enum knowledge kind. However you need to use the enum module within the Python commonplace library to create enumerations. And this tutorial will train you the way.
Let’s get began!
Enum stands for “enumeration” and consists of a set of predefined named constants. These constants are sometimes associated. Frequent examples embrace months in a 12 months, days of the week, grades, order and job statuses.
To sum up: An enum is basically a group of associated constants, the place every fixed has a significant title related to it.
In Python, you may create enums utilizing the enum module (which we’ll do shortly!).
Why Use Enums
Utilizing enums helps enhance code readability and maintainability. This is’ how:
- Enums improve code readability by changing magic numbers or strings with significant labels. Additionally they make the code extra self-documenting because the names of enum members convey their function.
- Enums enhance code maintainability by offering a easy approach to outline and handle associated constants.
- By limiting variable assignments to solely legitimate enum values, enums additionally guarantee kind security.
- Enums facilitate simple iteration over and comparability of associated constants.
Now let’s create our first enumeration in Python.
We’ll create a TaskStatus
enum that takes the next 4 names and values:
Picture by Creator
First, we import the Enum
class from the enum module to create enums.
We then outline a brand new class TaskStatus
that inherits from Enum
to create an enumeration. Every member is outlined with a singular title and an non-obligatory worth like so:
from enum import Enum
class TaskStatus(Enum):
TODO = 0
IN_PROGRESS = 1
DONE = 2
ABANDONED = -1
All enum members we create are situations of the Enum class. It’s possible you’ll confirm it by calling the isinstance()
perform as proven:
print(isinstance(TaskStatus.TODO,Enum))
Let’s print out all of the members within the TaskStatus
enum by casting it into an inventory:
You must see the next output:
Output >>>
[<TaskStatus.TODO: 0>, <TaskStatus.IN_PROGRESS: 1>, <TaskStatus.DONE: 2>, <TaskStatus.ABANDONED: -1>]
All enum members have a title and a worth. That means you may entry enum members utilizing their names, like TaskStatus.TODO
. Otherwise you entry them by worth, like TaskStatus(0)
.
Now that we’ve created a easy TaskStatus
enum, let’s learn to carry out easy duties equivalent to iterating over the enum members.
Iterating Over Enums
In Python, you may work with enums just about the identical approach you’re employed with any iterable. For instance, you need to use the len()
perform to rely the variety of enum members:
num_statuses = len(TaskStatus)
print(num_statuses)
You can even iterate over enums simply the way in which you’d over a Python iterable equivalent to checklist. Within the following for loop, we entry each the title and worth of every enum member and print them out:
for standing in TaskStatus:
print(standing.title, standing.worth)
Right here’s the output:
Output >>>
TODO 0
IN_PROGRESS 1
DONE 2
ABANDONED -1
Ordering in Enums
Within the instance, the standing and the corresponding numeric worth are as follows:
- TODO: 0
- IN_PROGRESS: 1
- DONE: 2
- ABANDONED: -1
However you can even use the default ordering through the use of the auto()
helper perform. If you achieve this, when you have ‘n’ members within the enum, the values assigned are 1 by n. However you may cross in a begin worth, say ok, auto(ok)
for the enumeration to start out at ok and go as much as ok + n.
Let’s modify the TaskStatus
enum as proven:
from enum import Enum, auto
class TaskStatus(Enum):
TODO = auto()
IN_PROGRESS = auto()
DONE = auto()
ABANDONED = auto()
Now let’s print out the members:
We see that the values are 1 to 4 as anticipated:
Output >>>
[<TaskStatus.TODO: 1>, <TaskStatus.IN_PROGRESS: 2>, <TaskStatus.DONE: 3>, <TaskStatus.ABANDONED: 4>]
Now let’s construct on the TaskStatus
enum that we’ve got. Create a job.py file in your working listing with the next model of the enum:
# job.py
from enum import Enum
class TaskState(Enum):
TODO = 0
IN_PROGRESS = 1
DONE = 2
ABANDONED = -1
Say we’ve got a job with a reputation and a present standing. And the legitimate transitions between states are as proven:
Picture by Creator
Let’s create a Process
class:
class Process:
def __init__(self, title, state):
self.title = title
self.state = state
def update_state(self, new_state):
# Outline legitimate state transitions based mostly on the present state
valid_transitions = {
TaskState.TODO: [TaskState.IN_PROGRESS, TaskState.ABANDONED],
TaskState.IN_PROGRESS: [TaskState.DONE, TaskState.ABANDONED],
TaskState.DONE: [],
TaskState.ABANDONED: []
}
# Test if the brand new state is a legitimate transition from the present state
if new_state in valid_transitions[self.state]:
self.state = new_state
else:
increase ValueError(f"Invalid state transition from {self.state.title} to {new_state.title}")
Now we have an update_status()
methodology that checks if the transition to the brand new state is legitimate given the present standing. For invalid transitions, a ValueError exception is raised.
Right here’s an Occasion of the Process
class: the “Write Report” job with standing TODO:
# Create a brand new job with the preliminary state "To Do"
job = Process("Write Report", TaskState.TODO)
# Print the duty particulars
print(f"Process Title: {job.title}")
print(f"Present State: {job.state.title}")
Output >>>
Process Title: Write Report
Present State: TODO
Updating the standing of the duty to IN_PROGRESS ought to work because it’s a legitimate state transition:
# Replace the duty state to "In Progress"
job.update_state(TaskState.IN_PROGRESS)
print(f"Up to date State: {job.state.title}")
Output >>> Up to date State: IN_PROGRESS
And as soon as the duty is full, we will replace its standing to DONE:
# Replace the duty state to "DONE"
job.update_state(TaskState.DONE)
print(f"Up to date State: {job.state.title}")
Output >>> Up to date State: DONE
However in case you attempt to replace the standing to an invalid one, equivalent to making an attempt to replace DONE to TODO, you’ll run into ValueError exception:
# Try to replace the duty state to an invalid state
job.update_state(TaskState.TODO)
Right here’s the traceback of the ValueError raised due to invalid state transition from DONE to TODO:
Traceback (most up-to-date name final):
File "/house/balapriya/enums/job.py", line 46, in
job.update_state(TaskState.TODO)
File "/house/balapriya/enums/job.py", line 30, in update_state
increase ValueError(f"Invalid state transition from {self.state.title} to {new_state.title}")
ValueError: Invalid state transition from DONE to TODO
On this tutorial, we discovered the best way to construct enumerations in Python by coding a easy TaskStatus enum. We discovered the best way to entry enum members and iterate over them.
Additionally, we discovered how default ordering works in case you select to make use of the auto()
helper perform to set the values for enum members. We then tried utilizing the TaskStatus enum in a extra useful instance.
Yow will discover the code examples on GitHub. I’ll see you all quickly in one other Python tutorial. Till then, blissful coding!
Bala Priya C is a developer and technical author from India. She likes working on the intersection of math, programming, knowledge science, and content material creation. Her areas of curiosity and experience embrace DevOps, knowledge science, and pure language processing. She enjoys studying, writing, coding, and occasional! Presently, she’s engaged on studying and sharing her information with the developer neighborhood by authoring tutorials, how-to guides, opinion items, and extra.