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

Related articles