How can I output blank value in python yaml file

35,445

Solution 1

For None type to be read from python use null in yaml

A YAML file test.yml like this

foo: null
bar: null

will be read by python as

import yaml
test = yaml.load(open('./test.yml'))
print(test)

foo: None
bar: None

Solution 2

If you load a YAML src

allow:

into Python you get None assigned to the key allow, that is the correct behaviour.

If you use ruamel.yaml (of which I am the author), and its RoundTripDumper, None is written as you want it (which is IMO the most readable, although not explicit):

import ruamel.yaml

print ruamel.yaml.dump(dict(allow=None), Dumper=ruamel.yaml.RoundTripDumper)

will give you:

allow:

You can also properly round-trip this:

import ruamel.yaml

yaml_src = """
allow:
key2: Hello  # some test

"""

data = ruamel.yaml.load(yaml_src, ruamel.yaml.RoundTripLoader)
print('#### 1')
print(data['allow'])
print('#### 2')
print(ruamel.yaml.dump(data, Dumper=ruamel.yaml.RoundTripDumper))

print('#### 3')

print(type(data))

to get as output:

#### 1
None
#### 2
allow:
key2: Hello  # some test


#### 3
<class 'ruamel.yaml.comments.CommentedMap'>

In the above, data is a subclass of ordereddict, which is necessary to keep track of the flowstyle of the input, handling comments attached to lines, order of the keys, etc..
Such a subclass can be created on the fly, but it is normally easier to start with some readable and well formatted YAML code (possible already saved on disc) and then update/extend the values.

Solution 3

from yaml import SafeDumper
import yaml

data = {'deny': None, 'allow': None}

SafeDumper.add_representer(
    type(None),
    lambda dumper, value: dumper.represent_scalar(u'tag:yaml.org,2002:null', '')
  )

with open('./yadayada.yaml', 'w') as output:
  yaml.safe_dump(data, output, default_flow_style=False)

There is a way to do this built into python yaml itself. The above code will produce a file containing:

allow:
deny:

Solution 4

Using replace, this seems straightforward:

import yaml

fname = 'test.yaml'
with open(fname, "w") as f:
    yaml_str = yaml.safe_dump({'allow':'', 'deny': ''},
                            default_flow_style=False,
                            width=50, 
                            indent=4).replace(r"''", '')
    f.write(yaml_str)

Is there a reason why you want to avoid replace?

There is the drawback that re-loading the yaml file does not reproduce your input:

>>> print yaml.safe_load(open(fname))
{'deny': None, 'allow': None}
Share:
35,445
user3214546
Author by

user3214546

Updated on December 21, 2020

Comments

  • user3214546
    user3214546 over 3 years

    I am writing yaml file like this

    with open(fname, "w") as f:
         yaml.safe_dump({'allow':'', 'deny': ''}, f,
                        default_flow_style=False, width=50, indent=4)
    

    This outputs:

    allow: ''
    

    I want to output as

    allow:
    

    How can I do that?