How to pickle complex enum values in Python
enums, pickle, python
Solution
Don't use a custom class as the enum values; there is no need here. Your specific example doesn't need a separate class at all, you could just use:
class Colors(Enum):
GREEN = 1
BLUE = 2
def __str__(self):
return self.name
@property
def counter(self):
return self.value
This has better `str()` and `.counter` behaviour; your code requires `str()` to be applied to `Color.<name>.value` rather than directly to `Color.<name>`.
For other custom methods and attributes, put those directly on the `Enum` subclass and they'll be part of the enum members too. If you need more values per entry, set a tuple and pull that tuple apart in a `__init__` method. The documentation has an excellent Planet example that illustrates this further.
Demo:
>>> Colors.BLUE
<Colors.BLUE: 2>
>>> Colors.BLUE.value
2
>>> Colors.BLUE.counter
2
>>> str(Colors.BLUE)
'BLUE'
>>> Colors.BLUE is loads(dumps(Colors.BLUE))
True
Problem
When I try to unpickle pickled complex enum instance, I always get "ValueError: BLUE is not a valid Colors". Is there any way how to pickle and unpickle? ``` from pickle import loads, dumps from enum import Enum class ColorType(object): def __init__(self, counter, name): self.counter = counter self.name = name def __str__(self): return self.name class Colors(Enum): GREEN = ColorType(1, 'GREEN') BLUE = ColorType(2, 'BLUE') color = Colors.BLUE print(color is loads(dumps(color))) ``` I am using Python 2.7.