To expand on @pault comment, you could use try/except, but it would work better in a better indented blocks (optionally, you can also chain the with statement):
from json.decoder import JSONDecodeError
with open(filename, 'a+') as infile, open(filename, 'w') as outfile:
try:
old_data = json.load(infile)
data = old_data + obj
json.dump(data, outfile)
except JSONDecodeError:
pass
Answer from Sazzy on Stack OverflowTo expand on @pault comment, you could use try/except, but it would work better in a better indented blocks (optionally, you can also chain the with statement):
from json.decoder import JSONDecodeError
with open(filename, 'a+') as infile, open(filename, 'w') as outfile:
try:
old_data = json.load(infile)
data = old_data + obj
json.dump(data, outfile)
except JSONDecodeError:
pass
import os
os.stat("file").st_size == 0
python - Forcing json to dump a json object even when list is empty - Stack Overflow
arrays - Appending into an empty JSON file in python - Stack Overflow
Python writes empty json file - Stack Overflow
Python: Json file become empty - Stack Overflow
In the tell_favorite_number() try to replace
favorite_number = get_favorite_number()
with
try:
favorite_number = get_favorite_number()
except:
favorite_number = 0
You should check out try except blocks
import json
def get_new_favorite_number():
favorite_number = input('please enter your favorite number')
filename = 'favorite_number.json'
with open(filename, 'w') as f_obj:
json.dump(favorite_number, f_obj)
def get_favorite_number():
filename = 'favorite_number.json'
with open(filename) as f_obj:
try:
favorite_number = json.load(f_obj)
except:
favorite_number = None
return favorite_number
def tell_favorite_number():
favorite_number = get_favorite_number()
if favorite_number is not None:
print('your favorite number is ' + str(favorite_number))
else:
favorite_number = get_new_favorite_number()
You get this error because the json library tries to decode a non exsistent value.
You can simply store your number in a text file, or handle the exception. In your except block you can call get_new_favorite_number.
With storing your value in a text file, you can easily edit it by hand.
Modify your reader script to this:
with open('favoriteColor.json') as inFile:
try:
colors = json.load(inFile)
except ValueError:
colors = []
This attempts to load the file as a json. If it fails due to a value error, we know that this is because the json is empty. Therefore we can just assign colors to an empty list. It is also preferable to use the "with" construct to load files since it closes them automatically.
I wouldn't take the approach you're trying. I would instead json.dump a dictionary, eg:
d = {'var1': '123', 'var2': [1, 2, 3]}
json.dump(d, fileout)
Then use dict.get to default it to a suitable value:
json_dict = json.load(filein)
favColor = json_dict.get('favColor', [])
Then you still have compulsory values that can except if not present using [] notation.
Puts the logic of missing values in your code instead of the json parsers...
I can't see any issues with the code itself, but there can be an issue with the execution environment. Are you running the code in a multi-threaded environment or running multiple instances of the same program at once?
This situation can arise if this code is executed parallelly and multiple threads/processes try to access the file at the same time. Try logging each time the function was executed and if the function was executed successfully. Try exception handlers and error logging.
If this is a problem, using buffers or singleton pattern can solve the issue.
As @Chels said, the file is truncated when it's opened with 'w'. That doesn't explain why it stays that way; I can only imagine that happening if your code crashed. Maybe you need to check logs for code crashes (or change how your code is run so that crash reasons get logged, if they aren't).
But there's a way to make this process safer in case of crashes. Write to a separate file and then replace the old file with the new file, only after the new file is fully written. You can use os.replace() for this. You could do this simply with a differently-named file:
with open(".cam_settings.json.tmp", 'w') as f:
json.dump(cam_settings, f, indent=4)
os.replace(".cam_settings.json.tmp", "cam_settings.json")
Or you could use a temporary file from the tempfile module.