# 类的序列化和反序列化

# 第一种:yaml.YAMLObject

  • yaml.YAMLObject用元类来注册一个构造器(也就是代码里的 init() 方法),让你把yaml节点转为Python对象实例
  • 用表示器(也就是代码里的 repr() 函数)来让你把Python对象转为yaml节点
import yaml
class Person(yaml.YAMLObject):
    yaml_tag = '!person'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return '%s(name=%s, age=%d)' % (self.__class__.__name__, self.name, self.age)

james = Person('James', 20)

print (yaml.dump(james))  # Python对象实例转为yaml

lily = yaml.load('!person {name: Lily, age: 19}')

print (lily)  # yaml转为Python对象实例
!person {age: 20, name: James}

Person(name=Lily, age=19)

# 第二种:yaml.add_constructor 和 yaml.add_representer

  • 可以为正常的类添加constructor和representer达到和上面一致的效果。
import yaml


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

    def __repr__(self):
        return 'Person(%s, %s)' % (self.name, self.age)

james = Person('James', 20)
print (yaml.dump(james))  # 没加表示器之前


def person_repr(dumper, data):
    return dumper.represent_mapping(u'!person', {"name": data.name, "age": data.age})  # mapping表示器,用于dict

yaml.add_representer(Person, person_repr)  # 用add_representer方法为对象添加表示器
print (yaml.dump(james))  # 加了表示器之后


def person_cons(loader, node):
    value = loader.construct_mapping(node)  # mapping构造器,用于dict
    name = value['name']
    age = value['age']
    return Person(name, age)

yaml.add_constructor(u'!person', person_cons)  # 用add_constructor方法为指定yaml标签添加构造器
lily = yaml.load('!person {name: Lily, age: 19}')
print (lily)
!!python/object:__main__.Person {age: 20, name: James}

!person {age: 20, name: James}

Person(Lily, 19)