Reputation: 6831
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?
Upvotes: 51
Views: 85478
Reputation: 1709
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
Upvotes: 103
Reputation: 76792
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.
Upvotes: 13
Reputation: 377
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:
Upvotes: 24
Reputation: 831
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}
Upvotes: 7