Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do yaml.safe_dump() and .safe_load() of Python object without yaml.YAMLObject?

I want to serialize some object with yaml.safe_dump(). How can I serialize Python objects with add_representer() and add_constructor() ...

I can not add yaml.YAMLObject to Thing (third party module) and not want use.

I do such dump:

import yaml

class Thing(object):
  def __init__(self, name):
    self.name = name

def Thing_representer(dumper, data):
  return dumper.represent_mapping('!Thing', data.__dict__)

yaml.SafeDumper.add_representer(Thing, Thing_representer)
safe_dump = yaml.safe_dump(t)
print safe_dump

It works fine but I have no idea how to do constructor?

def Thing_constructor(loader, data):
  thing = Thing()
  return thing.__dict__.update(loader.construct_mapping(data))

yaml.SafeLoader.add_constructor('!Thing', Thing_constructor)
yaml.safe_load(safe_dump)

It throws exception TypeError: __init__() takes exactly 2 arguments (1 given) and should throw since constructor requires parameters. Maybe there is another option to construct object skipping constructor?

like image 278
Chameleon Avatar asked Oct 22 '25 15:10

Chameleon


1 Answers

You cannot construct Thing() without handing in the name. You can solve that in various ways, but the following should work.

def thing_constructor(self, node):
    name = None
    for x in node.value:
        if x[0].value == 'name':
            name = x[1].value
    return Thing(name)


yaml.SafeLoader.add_constructor('!Thing', thing_constructor)

res = yaml.safe_load(safe_dump)
print res.name

You can simplify the setting of the name parameter, but this way it is more extensible if Thing would have taken more parameters.

like image 186
Anthon Avatar answered Oct 25 '25 04:10

Anthon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!