简体   繁体   中英

YAML to use repr/str when printing an object

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?

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.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM