Skip to main content

Python Enum to String without Class Name

· 6 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

When using Python Enums, the default string output includes the class name (e.g., <MyEnum.MEMBER: 'value'>), which is often unsuitable for clean logging, API responses, or direct printing. This article demonstrates how to leverage Python's dunder methods (__str__, __repr__, __format__) to gain complete control over the string representation of your Enum members.

The Default Problem Statement

By default, an Enum member prints its full, verbose representation, including the class name and the member name, which is usually not what's desired when serializing to a simple string.

from enum import Enum

class Color(Enum):
RED = 'red'
GREEN = 'green'

my_color = Color.RED
# Default print output:
# print(my_color) # Output: Color.RED
# print(str(my_color)) # Output: Color.RED

Solution 1: Controlling Standard String Output with __str__

The __str__ method controls the output when an object is converted to a string using str() or when it is printed via the print() function. Overriding this method is the primary way to remove the class name from basic output.

class OutputMode(Enum):
COMPACT = 1
VERBOSE = 2

# Override __str__ to return only the member's value or name
def __str__(self):
# Recommended: return the raw value, which is useful for APIs
return str(self.value)

# Usage:
mode = OutputMode.COMPACT
print(f"Current mode value: {mode}") # Calls __str__ implicitly
print(str(mode))
# Output: 1
# Output: 1

class RoleNameOnly(Enum):
ADMIN = 'admin'

def __str__(self):
# Alternative: return the member's name (ALL_CAPS)
return self.name

Solution 2: Controlling Debug and List Output with __repr__

While __str__ controls the friendly output, __repr__ controls the official string representation used for debugging, logging collections (like lists and dictionaries), and interactive shell output. Experts often leave __repr__ verbose for debugging but may override it for specific needs.

class DebugStatus(Enum):
ACTIVE = 1
INACTIVE = 0

def __str__(self):
return self.name.lower() # Friendly output

# Override __repr__ for clean list display
def __repr__(self):
# Return a clean, non-class-prefixed string representation
return f"'{self.name}'"

# Usage:
statuses = [DebugStatus.ACTIVE, DebugStatus.INACTIVE]
print(f"String output: {statuses[0]}")
# Output: active (Calls __str__)

print(f"List representation: {statuses}")
# Output: ['ACTIVE', 'INACTIVE'] (Calls __repr__ for each element)

Solution 3: Custom Formatting in f-strings with __format__

The __format__ method allows you to define specialized formatting based on a format specifier provided in an f-string (e.g., {member:spec}). This is highly advanced and useful for converting Enum values into hex, binary, or lowercase on the fly.

class ConfigFlag(Enum):
READ = 1
WRITE = 2
EXECUTE = 4

def __format__(self, format_spec):
if format_spec == 'hex':
# Format the raw value as hexadecimal
return f"0x{self.value:X}"
elif format_spec == 'lower':
# Format the member name in lowercase
return self.name.lower()

# Fallback to default formatting if specifier is not handled
return super().__format__(format_spec)

# Usage:
flag = ConfigFlag.EXECUTE
print(f"Hex output: {flag:hex}")
# Output: 0x4

print(f"Lowercase output: {flag:lower}")
# Output: execute

Solution 4: Injecting __str__ via Mixins

To avoid repeating the boilerplate __str__ implementation across multiple Enum classes, you can use a simple mixin that provides the desired behavior.

class ValueStrMixin:
"""Mixin to ensure __str__ always returns the raw value."""
def __str__(self):
return str(self.value)

class SimpleStatus(ValueStrMixin, Enum):
ON = "active"
OFF = "inactive"

class ErrorCode(ValueStrMixin, Enum):
MISSING_PARAM = 400
ACCESS_DENIED = 403

# Usage:
print(f"Status output: {SimpleStatus.ON}")
# Output: active

print(f"Error output: {ErrorCode.ACCESS_DENIED}")
# Output: 403

# Annotation: When SimpleStatus is instantiated, it inherits __str__ from
# ValueStrMixin, ensuring consistent formatting across all inheriting Enums.

Sources and Further Reading

  1. Python Documentation - object.__str__ and __repr__
  2. Python Documentation - object.__format__
  3. Python Documentation - Customizing Enumerations
  4. Real Python - Python Enum Dunder Methods