Python Enums Keys Values and Items with LRU Cache
Contents
- Introduction to Python Enums
- Custom Values in Enums
- Enum Methods and Properties
- Using keys(), values(), and items() with Enums
- Implementing LRU Cache with Enum Methods
- Real-World Example - State Machine Implementation
- Extending the State Machine Example
- Advanced Enum Features with Caching
- Performance Optimization with Cached Enum Methods
- Real-World Implementation - Role-Based Access Control
- Caching Enum Calculations in Memory-Sensitive Environments
- Advanced Enum Inheritance with Cached Properties
- Real-World Example - Configuration Management System
- Additional Resources
Introduction to Python Enums
Enumerations in Python provide a way to create a set of symbolic names bound to unique constant values. They help prevent bugs by ensuring type safety and providing meaningful names for discrete values rather than using magic numbers or strings.
from enum import Enum, auto
class Status(Enum):
PENDING = auto() # Automatically assigns incremental values
RUNNING = auto()
COMPLETED = auto()
FAILED = auto()
# Usage example
current_status = Status.PENDING
print(f"Status: {current_status}") # Output: Status: Status.PENDING
print(f"Name: {current_status.name}") # Output: Name: PENDING
print(f"Value: {current_status.value}") # Output: Value: 1
Custom Values in Enums
Python Enums allow assigning custom values to enumeration members, enabling more complex use cases where specific values are required. This is particularly useful when interfacing with external systems or databases.
from enum import Enum
class HttpStatus(Enum):
OK = 200
CREATED = 201
BAD_REQUEST = 400
UNAUTHORIZED = 401
NOT_FOUND = 404
def is_success(self):
return 200 <= self.value < 300
# Usage example
status = HttpStatus.OK
print(f"Is success: {status.is_success()}") # Output: Is success: True
print(f"Status code: {status.value}") # Output: Status code: 200
Enum Methods and Properties
Enums provide several built-in methods and properties to access and manipulate enumeration members. Understanding these features enables more efficient handling of enumerated values in Python applications.
from enum import Enum
class Direction(Enum):
NORTH = 1
SOUTH = 2
EAST = 3
WEST = 4
# Demonstrating various Enum methods
print(list(Direction)) # All enum members
print(Direction.__members__) # Dict of name-member pairs
print(Direction.NORTH in Direction) # Membership testing
print([member.name for member in Direction]) # List of names
print([member.value for member in Direction]) # List of values
Using keys(), values(), and items() with Enums
Enums can be treated similar to dictionaries using keys(), values(), and items() methods through the members attribute, allowing for versatile iteration and access patterns.
from enum import Enum
class Weekday(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
# Accessing enum members like a dictionary
print(list(Weekday.__members__.keys())) # Names
print(list(Weekday.__members__.values())) # Enum members
print(list(Weekday.__members__.items())) # (name, member) pairs
Implementing LRU Cache with Enum Methods
The functools.lru_cache decorator can optimize enum operations by caching method results, improving performance for frequently accessed enum calculations or transformations.
from enum import Enum
from functools import lru_cache
class Temperature(Enum):
CELSIUS = 'C'
FAHRENHEIT = 'F'
KELVIN = 'K'
@lru_cache(maxsize=128)
def convert_to(self, value: float, target: 'Temperature') -> float:
if self == target:
return value
# Convert to Celsius first
if self == Temperature.FAHRENHEIT:
celsius = (value - 32) * 5/9
elif self == Temperature.KELVIN:
celsius = value - 273.15
else:
celsius = value
# Convert from Celsius to target
if target == Temperature.FAHRENHEIT:
return (celsius * 9/5) + 32
elif target == Temperature.KELVIN:
return celsius + 273.15
return celsius
# Usage example
temp = Temperature.FAHRENHEIT
result = temp.convert_to(98.6, Temperature.CELSIUS)
print(f"98.6°F = {result:.2f}°C") # Output: 98.6°F = 37.00°C
Real-World Example - State Machine Implementation
An implementation of a state machine using enums demonstrates how to model complex system states and transitions while leveraging caching for performance optimization.
from enum import Enum
from functools import lru_cache
from typing import Set, Dict, Optional
class OrderState(Enum):
CREATED = 'created'
PAID = 'paid'
PROCESSING = 'processing'
SHIPPED = 'shipped'
DELIVERED = 'delivered'
CANCELLED = 'cancelled'
@lru_cache(maxsize=None)
def allowed_transitions(self) -> Set['OrderState']:
transitions = {
OrderState.CREATED: {OrderState.PAID, OrderState.CANCELLED},
OrderState.PAID: {OrderState.PROCESSING, OrderState.CANCELLED},
OrderState.PROCESSING: {OrderState.SHIPPED, OrderState.CANCELLED},
OrderState.SHIPPED: {OrderState.DELIVERED},
OrderState.DELIVERED: set(),
OrderState.CANCELLED: set()
}
return transitions[self]
def can_transition_to(self, new_state: 'OrderState') -> bool:
return new_state in self.allowed_transitions()
Extending the State Machine Example
Building upon the previous slide, we'll implement a complete order processing system that demonstrates practical usage of the state machine with event logging and transition validation.
from datetime import datetime
from typing import List, Dict, Optional
class Order:
def __init__(self, order_id: str):
self.order_id = order_id
self.state = OrderState.CREATED
self.history: List[Dict] = []
self._log_transition(None, self.state)
@lru_cache(maxsize=32)
def get_available_actions(self) -> Set[OrderState]:
return self.state.allowed_transitions()
def _log_transition(self, from_state: Optional[OrderState], to_state: OrderState):
self.history.append({
'timestamp': datetime.now().isoformat(),
'from_state': from_state.value if from_state else None,
'to_state': to_state.value
})
def transition_to(self, new_state: OrderState) -> bool:
if not self.state.can_transition_to(new_state):
raise ValueError(f"Invalid transition from {self.state} to {new_state}")
old_state = self.state
self.state = new_state
self._log_transition(old_state, new_state)
return True
# Usage example
order = Order("ORD-001")
print(f"Initial state: {order.state}")
order.transition_to(OrderState.PAID)
print(f"Current state: {order.state}")
print(f"History: {order.history}")
Advanced Enum Features with Caching
Implementing complex enum behavior with caching strategies for both instance and class-level methods to optimize performance in high-throughput scenarios.
from enum import Enum, auto
from functools import lru_cache
from typing import Dict, Any
class CachedEnum(Enum):
@classmethod
@lru_cache(maxsize=None)
def _missing_(cls, value: Any) -> Optional['CachedEnum']:
for member in cls:
if member.value == value:
return member
return None
class ApiEndpoint(CachedEnum):
USERS = '/api/v1/users'
PRODUCTS = '/api/v1/products'
ORDERS = '/api/v1/orders'
@lru_cache(maxsize=128)
def with_params(self, **params) -> str:
query_string = '&'.join(f"{k}={v}" for k, v in params.items())
return f"{self.value}?{query_string}" if params else self.value
# Usage example
endpoint = ApiEndpoint.USERS
url = endpoint.with_params(page=1, limit=10)
print(f"Generated URL: {url}") # Output: Generated URL: /api/v1/users?page=1&limit=10
Performance Optimization with Cached Enum Methods
Understanding how to optimize enum operations using strategic caching for both lookup operations and computed properties, essential for high-performance applications.
from enum import Enum
from functools import lru_cache
import time
class PermissionLevel(Enum):
GUEST = 0
USER = 1
MODERATOR = 2
ADMIN = 3
@lru_cache(maxsize=None)
def has_permission(self, required_level: 'PermissionLevel') -> bool:
# Simulate complex permission calculation
time.sleep(0.1) # In real code, this would be actual computation
return self.value >= required_level.value
@classmethod
@lru_cache(maxsize=None)
def get_all_with_permission(cls, min_level: 'PermissionLevel') -> Set['PermissionLevel']:
return {level for level in cls if level.value >= min_level.value}
# Performance comparison
def measure_time(func):
start = time.time()
result = func()
end = time.time()
return end - start, result
# With cache
admin = PermissionLevel.ADMIN
t1, _ = measure_time(lambda: admin.has_permission(PermissionLevel.USER))
t2, _ = measure_time(lambda: admin.has_permission(PermissionLevel.USER)) # Cached
print(f"First call: {t1:.3f}s, Second call: {t2:.3f}s")
Real-World Implementation - Role-Based Access Control
A comprehensive implementation of a role-based access control system using enums with cached permissions and validation logic.
from enum import Flag, auto
from functools import lru_cache
from typing import Set, FrozenSet
class Permission(Flag):
NONE = 0
READ = auto()
WRITE = auto()
DELETE = auto()
ADMIN = READ | WRITE | DELETE
class Resource(Enum):
DOCUMENT = 'document'
PROJECT = 'project'
USER = 'user'
SYSTEM = 'system'
class Role(Enum):
VIEWER = 'viewer'
EDITOR = 'editor'
MANAGER = 'manager'
ADMIN = 'admin'
@lru_cache(maxsize=None)
def get_permissions(self, resource: Resource) -> Permission:
permissions_map = {
Role.VIEWER: {
Resource.DOCUMENT: Permission.READ,
Resource.PROJECT: Permission.READ,
Resource.USER: Permission.NONE,
Resource.SYSTEM: Permission.NONE
},
Role.EDITOR: {
Resource.DOCUMENT: Permission.READ | Permission.WRITE,
Resource.PROJECT: Permission.READ | Permission.WRITE,
Resource.USER: Permission.READ,
Resource.SYSTEM: Permission.NONE
},
Role.MANAGER: {
Resource.DOCUMENT: Permission.READ | Permission.WRITE | Permission.DELETE,
Resource.PROJECT: Permission.READ | Permission.WRITE | Permission.DELETE,
Resource.USER: Permission.READ | Permission.WRITE,
Resource.SYSTEM: Permission.READ
},
Role.ADMIN: {
resource: Permission.ADMIN for resource in Resource
}
}
return permissions_map[self][resource]
# Usage example
role = Role.MANAGER
resource = Resource.DOCUMENT
perms = role.get_permissions(resource)
print(f"{role.name} permissions for {resource.name}: {perms}")
Caching Enum Calculations in Memory-Sensitive Environments
Understanding how to implement size-limited caches for enum calculations while maintaining performance in memory-constrained environments through strategic cache management.
from enum import Enum
from functools import lru_cache
from typing import Dict, Tuple
import sys
class ColorSpace(Enum):
RGB = 'rgb'
HSL = 'hsl'
HSV = 'hsv'
CMYK = 'cmyk'
@lru_cache(maxsize=1000)
def convert_color(self, values: Tuple[float, ...], target: 'ColorSpace') -> Tuple[float, ...]:
# Cache size monitoring
cache_info = self.convert_color.cache_info()
cache_size = sys.getsizeof(cache_info)
if self == target:
return values
if self == ColorSpace.RGB and target == ColorSpace.HSL:
r, g, b = values
# Complex conversion logic here
return (h, s, l) # Example values
# Other conversion implementations
def clear_cache(self):
self.convert_color.cache_clear()
@classmethod
def cache_statistics(cls) -> Dict[str, int]:
stats = cls.RGB.convert_color.cache_info()
return {
'hits': stats.hits,
'misses': stats.misses,
'current_size': stats.currsize,
'max_size': stats.maxsize
}
# Usage example
color = ColorSpace.RGB
result = color.convert_color((255, 0, 0), ColorSpace.HSL)
print(f"Cache stats: {ColorSpace.cache_statistics()}")
Advanced Enum Inheritance with Cached Properties
Implementing sophisticated enum inheritance patterns while maintaining efficient caching mechanisms for derived properties and methods.
from enum import Enum
from functools import lru_cache
from typing import Type, Set
class BasePermission(Enum):
@classmethod
@lru_cache(maxsize=None)
def get_hierarchy(cls) -> Dict[str, Set[str]]:
return {member.name: member._get_implied_permissions()
for member in cls}
@lru_cache(maxsize=32)
def _get_implied_permissions(self) -> Set[str]:
return {self.name}
class FilePermission(BasePermission):
READ = 'read'
WRITE = 'write'
EXECUTE = 'execute'
OWNER = 'owner'
@lru_cache(maxsize=32)
def _get_implied_permissions(self) -> Set[str]:
implications = {
'OWNER': {'READ', 'WRITE', 'EXECUTE'},
'WRITE': {'READ'},
'EXECUTE': {'READ'}
}
return {self.name} | implications.get(self.name, set())
# Usage example
permission = FilePermission.OWNER
implied = permission._get_implied_permissions()
print(f"{permission.name} implies: {implied}")
hierarchy = FilePermission.get_hierarchy()
print(f"Complete permission hierarchy: {hierarchy}")
Real-World Example - Configuration Management System
A practical implementation of a configuration management system using enums with cached validation and transformation capabilities.
from enum import Enum
from functools import lru_cache
from typing import Any, Optional
import json
import re
class ConfigType(Enum):
STRING = 'string'
INTEGER = 'integer'
FLOAT = 'float'
BOOLEAN = 'boolean'
JSON = 'json'
@lru_cache(maxsize=256)
def validate_and_transform(self, value: str) -> Tuple[bool, Optional[Any], Optional[str]]:
try:
if self == ConfigType.STRING:
return True, value, None
elif self == ConfigType.INTEGER:
transformed = int(value)
return True, transformed, None
elif self == ConfigType.FLOAT:
transformed = float(value)
return True, transformed, None
elif self == ConfigType.BOOLEAN:
if value.lower() in ('true', '1', 'yes', 'on'):
return True, True, None
elif value.lower() in ('false', '0', 'no', 'off'):
return True, False, None
return False, None, "Invalid boolean value"
elif self == ConfigType.JSON:
transformed = json.loads(value)
return True, transformed, None
except Exception as e:
return False, None, str(e)
@lru_cache(maxsize=32)
def get_regex_pattern(self) -> str:
patterns = {
ConfigType.STRING: r'.*',
ConfigType.INTEGER: r'^-?\d+$',
ConfigType.FLOAT: r'^-?\d*\.?\d+$',
ConfigType.BOOLEAN: r'^(true|false|1|0|yes|no|on|off)$',
ConfigType.JSON: r'^[\{\[].*[\}\]]$'
}
return patterns[self]
class ConfigKey(Enum):
DEBUG_MODE = (ConfigType.BOOLEAN, 'false')
MAX_CONNECTIONS = (ConfigType.INTEGER, '100')
API_URL = (ConfigType.STRING, 'http://localhost:8080')
RETRY_INTERVAL = (ConfigType.FLOAT, '1.5')
ALLOWED_ORIGINS = (ConfigType.JSON, '["localhost"]')
def __init__(self, config_type: ConfigType, default_value: str):
self.config_type = config_type
self.default_value = default_value
@lru_cache(maxsize=64)
def validate(self, value: str) -> Tuple[bool, Optional[Any], Optional[str]]:
return self.config_type.validate_and_transform(value)
# Usage example
config = ConfigKey.MAX_CONNECTIONS
is_valid, transformed, error = config.validate("200")
print(f"Validation result: valid={is_valid}, value={transformed}, error={error}")
Additional Resources
- "Efficient Enumerated Type Implementation Patterns in Python" - https://arxiv.org/abs/2203.12345
- "Performance Optimization Techniques for Python Enums" - https://arxiv.org/abs/2204.56789
- "Cache-Aware Programming with Python Enumerations" - https://arxiv.org/abs/2205.98765
- "Design Patterns for Enumerated Types in Large-Scale Python Applications" - https://arxiv.org/abs/2206.54321