Search code examples
pythonclassyamlruamel.yaml

How to initialize yaml parser/loader/dumper for a class


I want to initialize yaml with following parameters

from ruamel.yaml import YAML
...
def null_representer(self, data):
    return self.represent_scalar(u'tag:yaml.org,2002:null', u'null')

yaml = YAML()
yaml.representer.ignore_aliases = lambda *data: True
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.preserve_quotes = True
yaml.representer.add_representer(type(None), null_representer)

I wanted to know if there's a way I can initialize yaml like this to use in my class

class A:
   def __init__(self):
        self._yaml = (the yaml I initialized)

For example, python logging module has this fucntion -

import logging

def init_logging():
    log = logging.getLogger()
    log.setLevel(logging.INFO)
    sh = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
    sh.setFormatter(formatter)
    log.addHandler(sh)

class A:
   def __init__(self):
        self._log = logging.getLogger('A')

Solution

  • If you want the YAML() instance to be the global one that you already initialised, and class A is anywhere in the same file, you can just do

    def __init__(self):
        self._yaml = yaml
    

    as long as you don't make an instance of A before yaml is assigned to.

    If you have the class A in a different file, just import yaml from the Python file, just like you import getLogger. E.g. if the first code block is in myyaml.py:

    from util.myyaml import yaml
    

    Make sure you have (an empty) __init__.py files in the subdirectory util

    Of course you can also give an instance of class A its own YAML() instance:

    from ruamel.yaml import YAML
    
    def null_representer(self, data):
        return self.represent_scalar(u'tag:yaml.org,2002:null', u'null')
    
    class A:
       def __init__(self):
           self.yaml.load(.....)
    
       @property
       def yaml(self):
           try:
               return self._yaml
           except AttributeError:
               pass
           self._yaml = yaml = YAML()
           yaml.representer.ignore_aliases = lambda *data: True
           yaml.indent(mapping=2, sequence=4, offset=2)
           yaml.preserve_quotes = True
           yaml.representer.add_representer(type(None), null_representer)
           return yaml
    

    This is the way I usually do things. If self.yaml is not used in the __init__(), the instantiation of YAML() will be delayed until you first use it, which might speed up your program startup.