Exploring Enum Member Iteration: enum.EnumType.__reversed__() and Alternatives
What it is
- It provides a way to iterate over the members of an enum class in the reverse order of their definition.
- Introduced in Python 3.11,
enum.EnumType.__reversed__()
is a special method defined on the metaclass (EnumType
) of Python'senum
module.
How it works
- The
EnumType
metaclass is responsible for creating enum classes and managing their members. - When you define an enum class (e.g.,
Color = Enum(...)
), theEnumType
metaclass takes care of:- Setting up the enum members with their names and values.
- Handling member order (based on definition order).
- Providing methods like
__repr__()
,__str__()
, and iteration.
- The
__reversed__() Method
- The
__reversed__()
method is a dunder method (methods with double underscores) that gets called implicitly when you use thereversed()
built-in function on an enum class. - Its implementation within
EnumType
returns an iterator that yields the enum members in the reverse order they were defined in the enum class.
- The
Example
from enum import Enum
class Color(Enum):
RED = "Red"
GREEN = "Green"
BLUE = "Blue"
# Get the enumeration members (original order)
members = Color
# Iterate over members in original order (for reference)
print("Original Order:")
for member in members:
print(member)
# Get the reversed order of enumeration members
reversed_members = reversed(members) # Using reversed() built-in
# Iterate over members in reversed order
print("\nReversed Order:")
for member in reversed_members:
print(member)
Output
Original Order:
Color.RED
Color.GREEN
Color.BLUE
Reversed Order:
Color.BLUE
Color.GREEN
Color.RED
Key Points
- This can be useful in scenarios where you need to process enum members in a descending order based on their values or names.
- It provides a convenient way to access enum members in the opposite order they were defined.
enum.EnumType.__reversed__()
is specifically designed for enum classes.
Additional Notes
- For Python versions before 3.11, you can achieve reversed iteration using techniques like manually creating a list of members and reversing it.
- If you need more control over the order of iteration, you can define an explicit ordering using the
__order__ = True
class attribute on your enum class.
Accessing last defined enum member
from enum import Enum
class Size(Enum):
SMALL = 1
MEDIUM = 2
LARGE = 3
# Get the last defined member (using reversed order)
last_size = next(reversed(Size))
print(f"Last defined size: {last_size.name}")
This code retrieves the LARGE
size by iterating through the reversed members and accessing the first one (which is the last defined member).
Conditional processing based on reversed order
from enum import Enum
class PermissionLevel(Enum):
READ = 1
WRITE = 2
ADMIN = 3
# Check permission levels in descending order (highest to lowest)
for level in reversed(PermissionLevel):
if has_permission(level):
print(f"Granted permission level: {level.name}")
break # Exit loop on successful check
else:
print("No permission granted")
This code iterates through permission levels in reverse order (ADMIN, WRITE, READ). It checks if the user has the current permission level and breaks the loop on successful verification. The else
block handles cases where no permission is granted.
Customizing order with __order__ (Python 3.7+)
from enum import Enum
class Month(Enum):
DEC = "December" # Explicitly define order
JAN = "January"
FEB = "February"
Month.__order__ = True # Enable explicit order
# Iterate in defined order (DEC, JAN, FEB)
for month in Month:
print(month.name)
In this example, we define the order of months explicitly within the class using __order__ = True
. The reversed order would then be FEB
, JAN
, DEC
.
List Comprehension (Pythonic and Efficient)
- Iterate over the reversed list.
- Reverse the list using the built-in
reversed()
function. - Create a list of enum members in the original order using a list comprehension.
from enum import Enum
class Direction(Enum):
NORTH = 1
SOUTH = 2
EAST = 3
WEST = 4
# Create list of members and reverse it
members = list(Direction)
reversed_members = reversed(members)
# Iterate in reversed order
for member in reversed_members:
print(member)
Loop with Index Check (Simple for Short Enums)
- Use this index to access the member in the desired reversed order.
- Check the index of the current member against the total number of members minus 1.
- Loop through the enum members in the original order.
from enum import Enum
class Suit(Enum):
SPADES = 1
HEARTS = 2
DIAMONDS = 3
CLUBS = 4
# Loop and access in reversed order
total_members = len(Suit)
for i, member in enumerate(Suit):
reversed_index = total_members - 1 - i
print(f"Reversed order: {Suit(reversed_index + 1)}") # Access by value
- This function can be customized to perform additional operations on each member before returning them.
- Access the members one by one in reverse order using a loop or recursion.
- Define a function that takes the enum class as input.
from enum import Enum
def get_reversed_members(enum_class):
members = list(enum_class)
for i in range(len(members) - 1, -1, -1):
yield members[i]
class Shape(Enum):
CIRCLE = 1
SQUARE = 2
TRIANGLE = 3
# Use the custom function
for member in get_reversed_members(Shape):
print(member)