I'm having a little problem with a class activity of python. On this activity, i should create a I should create a system for a "small store" to be able to register products (in a JSON file) and then be able to load the file and make queries with the same loaded. Basically, the job is 90% completed, but i'm stuck trying to figure out why my products records isn't saving on the right structure of JSON. I don´t know why the JSON is not saving the items with the "[ ]" before and after the records.
global estoque
global contador_sinal
global carregar_flag
estoque = []
lista_produtos = [] # <--- HERE I CREATE THE LIST THAT RECEIVES PRODUCT REGISTRATIONS
contador_sinal = 0
contador = 0
carregar_flag = 0
class Produto: # <-- CREATING THE CLASS OF PRODUCTS
def __init__(self, codigo, nome, descricao, valor):
self.codigo = codigo
self.nome = nome
self.descricao = descricao
self.valor = valor
def gravar(): # <-- AND THIS IS THE FUNCTION THAT SAVES THE LIST PRODUCTS IN JSON
global contador_sinal
print("="*50)
print(" ","\nGravando Arquivo Externo dos Produtos...")
with open('data.json', 'w') as fp:
for item in lista_produtos:
if type(item) == Produto:
json.dump(item.__dict__, fp, indent=4)
fp.write("\n")
elif type(item) == dict:
json.dump(item, fp, indent=4)
time.sleep(1)
print(" ")
print("\033[32mARQUIVO SALVO COM SUCESSO!\033[0m\n")
fp.close()
contador_sinal = 1
return menu()
Here is how the information appears on the JSON after saved:
{
"codigo": 1,
"nome": "test1",
"descricao": "description",
"valor": 10.0
}
{
"codigo": 2,
"nome": "test2",
"descricao": "description",
"valor": 20.0
}
{
"codigo": 3,
"nome": "test3",
"descricao": "description",
"valor": 30.0
}
If someone knows how to fix this structure and the reason for being saved wrong, it would be a tremendous help.
CodePudding user response:
import json
class Produto: # <-- CREATING THE CLASS OF PRODUCTS
def __init__(self, codigo, nome, descricao, valor):
self.codigo = codigo
self.nome = nome
self.descricao = descricao
self.valor = valor
lista_produtos = [Produto(1, "test1", "description", 10), Produto(2, "test2", "description", 20), Produto(3, "test3", "description", 30)]
def gravar(): # <-- AND THIS IS THE FUNCTION THAT SAVES THE LIST PRODUCTS IN JSON
global contador_sinal
print("=" * 50)
print(" ", "\nGravando Arquivo Externo dos Produtos...")
data = [item.__dict__ if type(item) == Produto else item for item in lista_produtos] # <-- NON PRODUTO ITEMS ARE EXPECTED TO BE A DICT
with open('data.json', 'w') as fp:
json.dump(data, fp)
print(" ")
print("\033[32mARQUIVO SALVO COM SUCESSO!\033[0m\n")
def main():
gravar()
if __name__ == "__main__":
main()
Does this give the result you want?
CodePudding user response:
It is not possible to have valid JSON, append more data and get a still valid JSON. That is the problem of saving each dict (object in JSON speak) separately in a loop.
There are few ways to get around it:
Create a list of dicts in memory and save it as JSON just once.
Just for completness, because it is a hack. Add
[
and,
and]
characters at the beginning, as a separator and at the end of file respectively, to create a JSON list.My recommendation: Change your file format from JSON to newline delimited JSON. In the code posted all you need to change is to remove the
indent=4
parameter. Of course, the program reading such file must read it line-by-line and load each JSON line separately. That should be no problem.