Jak opravit chybu Python YAML namedtuple: yaml.representer.RepresenterError: ('cannot represent an object', ...

Problém:

Pokoušíte se yaml.safe_dump() objekt, který je (nebo obsahuje) namedtuple instance jako:

yaml_namedtuple_fix.py
import yaml
import collections

MyTuple = collections.namedtuple("MyTuple", ["a", "b", "c"])
mytuple = MyTuple(1,2,3)

yaml.safe_dump(mytuple)

což results v následující exception:

yaml_namedtuple_error.txt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/uli/.local/lib/python3.10/site-packages/yaml/__init__.py", line 269, in safe_dump
    return dump_all([data], stream, Dumper=SafeDumper, **kwds)
  File "/home/uli/.local/lib/python3.10/site-packages/yaml/__init__.py", line 241, in dump_all
    dumper.represent(data)
  File "/home/uli/.local/lib/python3.10/site-packages/yaml/representer.py", line 27, in represent
    node = self.represent_data(data)
  File "/home/uli/.local/lib/python3.10/site-packages/yaml/representer.py", line 58, in represent_data
    node = self.yaml_representers[None](self, data)
  File "/home/uli/.local/lib/python3.10/site-packages/yaml/representer.py", line 231, in represent_undefined
    raise RepresenterError("cannot represent an object", data)
yaml.representer.RepresenterError: ('cannot represent an object', MyTuple(a=1, b=2, c=3))

Řešení

Musíte přidat custom representer pro implicit conversion vašeho namedtuple na dict.

Před spuštěním yaml.safe_dump(), přidejte následující řádky:

represent_namedtuple_fix.py
import collections

def represent_namedtuple(dumper, data):
    return dumper.represent_dict(data._asdict())

yaml.SafeDumper.add_representer(MyTuple, represent_namedtuple)

Musíte add_representer() pro každý namedtuple, který používáte!

Nyní by yaml.safe_dump() call měl fungovat perfektně:

yaml_safe_dump_fixed.py
yaml.safe_dump(mytuple) # Returns 'a: 1\nb: 2\nc: 3\n'

Podívejte se na podobné články podle kategorie: Python