Reputation: 2825
I have a dictionary where keys are objects. These objects can be thought as tuple wrappers and they do implement both __hash__
and __repr__
.
example = {
Coordinates(0,0): Rome,
Coordinates(0,1): Zurich
}
I want to print the dictionary with yaml
, using the repr of the object. This would be the desired output:
(0, 0): Rome
(0, 1): Zurich
Instead, what I get is:
? !!python/object:__main__.Coordinates
x: 0
y: 0
: Rome
? !!python/object:__main__.Coordinates
x: 0
y: 1
: Zurich
I'm doing the transformation via:
import yaml
print(yaml.dump(example, allow_unicode=True, default_flow_style=False))
The only solution I found so far is to coerce everything to str()
manually myself. Is there a more elegant solution?
Upvotes: 2
Views: 576
Reputation: 39788
Assuming the type Coordinates
exists, this would be the setup:
import yaml
from yaml.resolver import BaseResolver
def coord_representer(dumper, data):
return dumper.represent_scalar(BaseResolver.DEFAULT_SCALAR_TAG,
data.__repr__())
yaml.add_representer(Coordinates, coord_representer)
The DEFAULT_SCALAR_TAG
ensures that PyYAML doesn't dump an explicit tag for the scalar (x, y)
. You may want to use an actual YAML sequence instead:
def coord_representer(dumper, data):
return dumper.represent_sequence(BaseResolver.DEFAULT_SEQUENCE_TAG,
[data.x, data.y], flow_style=[True, True])
This will yield [x, y]
, a YAML flow sequence. Problem is that this is tricky to read in again, as PyYAML would by default construct a list from it, which cannot be used as dict key.
Upvotes: 2