Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
yaml.dump() appending to file rather than overwriting
-
yaml.dump() appending to file rather than overwriting
how do i make set 'hi' to 1 and 'hello' to 1import yaml class myClass(): def __init__(self): self.configFile = open('config.yml', 'r+') self.config = yaml.load(self.configFile) self.config['hi'] = 1 self.config['hello'] = 1 yaml.dump( self.config, self.configFile, default_flow_style=False ) print(self.config) # returns {'hi': 1, 'hello': 1} myClass()
config file before:
hi: 0 hello: 0
after:
hi: 0 hello: 0 hi: 1 hello 1
what i want:
hi: 1 hello: 1
-
TL;DR:
- If you
open()
a file then you shouldclose()
it or even better, usewith open as
which will autoclose the file. - Opening files in
r+
mode is complicated.
c = {"hi": 0, "hello": 0} d = {"hi": 1, "hello": 1} # print(c | d) # Pythonista's version of Python is too old c.update(d) print(c)
- If you
-
the python dictionary is fine and printing what i want, printing the dict prints
{'hi': 1, 'hello': 1}
but when i dump it puts the yaml at the end of the file rather than overriding the file -
I haven't tested it, but I think the problem is that you aren't using file offsets correctly. Basically, right now you are reading the file, then continue writing from the last position you have read.
The best solution would be to seperate reading and writing the files.
import yaml class MyClass(): def __init__(self): with open('config.yml', 'r') as fin: self.config = yaml.load(fin) self.config['hi'] = 1 self.config['hello'] = 1 with open('config.yml', 'w') as fout: yaml.dump( self.config, fout, default_flow_style=False ) print(self.config) # returns {'hi': 1, 'hello': 1} MyClass()
Alternatively, call
self.configFile.seek(0)
after reading. This sets the read/write offset to the beginning of the file. Be warned that this only works if the new file content has at least the same length as the original file content, otherwise trailing bytes will remain! -
In a situation like this I would never write to the same file I read from.:
- read from the config file.
- Write to a new file.
- Rename the old config file to something like
..._bak.yml
. - Rename the new file to the name of the old config file.
My 2cts.
-
@halloleooo between 2 and 3: remove the previous bak file
-
@cvp Only when you use
os.rename
. If you usepathlib
'sPath.rename
I think it silently overwrites the old backup file. -
@halloleooo Ho. Nice, I didn't know, never too old to learn