The following is not working for me, with Python 3.4.7, ruamel.yaml version 0.15.35:
import sys
import enum
import ruamel.yaml
from ruamel.yaml import yaml_object
yaml = ruamel.yaml.YAML()
@yaml_object(yaml)
class Speed(enum.IntEnum):
Reverse = 0
Neutral = 1
Low = 2
Drive = 3
Park = 999
print("Neutral:", repr(Speed.Neutral))
yaml.dump(Speed.Neutral, sys.stdout)
I get a totally reasonable repr
:
Neutral: <Speed.Neutral: 1>
but the .dump()
raises:
ruamel.yaml.representer.RepresenterError: cannot represent an object: <enum 'Speed'>
If enum
's are not supported, is there something I can do to extend the enum
class I am using (or the subclass enum.IntEnum
I have created), eg a dunder method?
enum
is not supported out-of-the-box, essentially because the default dump
method is safe and therefore doesn't support arbitrary Python objects. That safety excludes types as enum
from the standard library as well.
What you should do is add a to_yaml
classmethod
to your Speed
class as described in the ruamel.yaml documentation :
import sys
import enum
import ruamel.yaml
from ruamel.yaml import yaml_object
yaml = ruamel.yaml.YAML()
@yaml_object(yaml)
class Speed(enum.IntEnum):
Reverse = 0
Neutral = 1
Low = 2
Drive = 3
Park = 999
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(
u'!Speed',
'{}-{}'.format(node._name_, node._value_)
)
yaml.dump(Speed.Neutral, sys.stdout)
which gives:
!Speed Neutral-1
...
You can of course adapt the string representation to your liking (and add a from_yaml
to be able to load the output back in).
Please note that you cannot add yaml_tag
as in the documentation example, as this would interfere with the enum
values.
I think you'll need to pass the enum by value.
yaml.dump(Speed.Neutral.value, sys.stdout)
Extended answer to add a @classmethod which calls .value as it's being passed
http://yaml.readthedocs.io/en/latest/dumpcls.html
import sys
import enum
import ruamel.yaml
from ruamel.yaml import yaml_object
yaml = ruamel.yaml.YAML()
@yaml_object(yaml)
class Speed(enum.IntEnum):
Reverse = 0
Neutral = 1
Low = 2
Drive = 3
Park = 999
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(u'!enum:', u'{.value}'.format(node))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.