Serializing YAML with PyYAML: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(10 intermediate revisions by the same user not shown)
Line 25: Line 25:
</syntaxhighlight>
</syntaxhighlight>


=PyYAML Concepts=
=Customizing Output=
==Customizing Output with <tt>dump()</tt> Parameters==
<syntaxhighlight lang='python'>
# with the default flow style, the document is rendered in a non-indented manner
print (yaml.dump(data, default_flow_style=False))
</syntaxhighlight>


PyYAML core model is centered on [[#Constructor|constructors]], [[#Representer|representers]] and [[#Tag|tags]].
==Customizing Output with Representers==


==Constructor==
The general process of using a custom representer of a data type is described here: {{Internal|YAML_in_Python#Representer|YAML in Python &#124; Representer}}
A constructor allows you to take a serialized YAML node and return a class instance.


==Representer==
===Configure <tt>yaml.dump()</tt> to render blank instead of <tt>null</tt>===
PyYAML <code>dump()</code> uses <code>Representer()</code> to represent <code>None</code>. By default, the representer <code>dump()</code> is configured with represents <code>None</code> as "null". To change that:


A representer is a function that serializes a class instance to a YAML node representation. The representer gets a <code>Dumper</code> instance as a first argument, and the data object as the second. The function must return the serialized representation of the data object instance, as a s string.
1. Define a method that "represents" <code>None</code>


<syntaxhighlight lang='py'>
<syntaxhighlight lang='py'>
def my_representer(dumper, data):
def representer_for_none(self, _):
 
    return self.represent_scalar('tag:yaml.org,2002:null', '')
</syntaxhighlight>
</syntaxhighlight>


The representers are registered with <code>add_representer()</code>. Representers can be added for specific types (such as <code>str</code> or <code>int</code>), or for ???
2. Add it to the module:
 
<syntaxhighlight lang='py'>
<syntaxhighlight lang='py'>
yaml.add_representer(str, my_representer)
import yaml
 
[...]
 
yaml.add_representer(type(None), represent_none)
</syntaxhighlight>
</syntaxhighlight>


==Tag==
This will render:
The tag uses the special character <code>!</code> preceding the tag name to label a YAML node.
<syntaxhighlight lang='py'>
A tag helps PyYAML to know which [[#Constructor|constructor]] or [[#Representer|representer]] to call.
d = {
    'a': None,
    'b': 'c'
}
</syntaxhighlight>
as:
<syntaxhighlight lang='yaml'>
a:
b: c
</syntaxhighlight>
 
<font color=darkkhaki>what is the lifecycle of the method registered to the module?</font>
===Configure <tt>yaml.dump()</tt> to render | multi-lines===
<syntaxhighlight lang='py'>
def literal_presenter(dumper, data):
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
 
def default_presenter(dumper, data):
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='')


=Customizing Output=
try:
==Customizing Output with <tt>dump()</tt> Parameters==
  yaml.add_representer(str, literal_presenter)
==Customizing Output with Representers==
  yaml_text = yaml.dump(config)
  return yaml_text
finally:
    yaml.add_representer(str, default_presenter)
</syntaxhighlight>

Latest revision as of 23:56, 7 December 2022

Internal

Overview

The process of serialization to YAML is rendering an in-memory data structure as a YAML-formatted string. The simplest sequence of statements that does that is:

import yaml

data = {
    'color': 'red',
    'size': 10,
    'parts': ['top', 'middle', 'bottom']
}

yaml_string = yaml.dump(data)

The YAML-formatted string will be:

color: red
parts:
- top
- middle
- bottom
size: 10

Customizing Output

Customizing Output with dump() Parameters

# with the default flow style, the document is rendered in a non-indented manner 
print (yaml.dump(data, default_flow_style=False))

Customizing Output with Representers

The general process of using a custom representer of a data type is described here:

YAML in Python | Representer

Configure yaml.dump() to render blank instead of null

PyYAML dump() uses Representer() to represent None. By default, the representer dump() is configured with represents None as "null". To change that:

1. Define a method that "represents" None

def representer_for_none(self, _):
    return self.represent_scalar('tag:yaml.org,2002:null', '')

2. Add it to the module:

import yaml

[...]

yaml.add_representer(type(None), represent_none)

This will render:

d = {
    'a': None,
    'b': 'c'
}

as:

a:
b: c

what is the lifecycle of the method registered to the module?

Configure yaml.dump() to render | multi-lines

def literal_presenter(dumper, data):
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')

def default_presenter(dumper, data):
     return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='')

try:
   yaml.add_representer(str, literal_presenter)
   yaml_text = yaml.dump(config)
   return yaml_text
finally:
    yaml.add_representer(str, default_presenter)