Skip to content Skip to sidebar Skip to footer

Cannot Write Dict Object As Correct Json To File

I try to read JSON from file, get values, transform them and back write to new file. { 'metadata': { 'info': 'important info' }, 'timestamp': '2018-04-06T12:19:38.611Z',

Solution 1:

Answer :

Change the write_json_to_file(...) method like this:

defwrite_json_to_file(file_name, json_content):
    withopen(file_name, 'w') as file:
        file.write(json_content)

Explanation:

The problem is, that when you're calling write_json_to_file(STACK_OUT_JSON, created_json) at the end of your script, the variable created_json contains a string - it's the JSON representation of the dictionary created in the create_json(...) function. But inside the write_json_to_file(file_name, json_content), you're calling:

json.dump(json_content, file)

You're telling the json module write the JSON representation of variable json_content (which contains a string) into the file. And JSON representation of a string is a single value encapsulated in double-quotes ("), with all the double-quotes it contains escaped by \. What you want to achieve is to simply write the value of the json_content variable into the file and not have it first JSON-serialized again.

Solution 2:

Problem

You're converting a dict into a json and then right before you write it into a file, you're converting it into a json again. When you retry to convert a json to a json it gives you the \" since it's escaping the " since it assumes that you have a value there.

How to solve it?

It's a great idea to read the json file, convert it into a dict and perform all sorts of operations to it. And only when you want to print out an output or write to a file or return an output you convert to a json since json.dump() is expensive, it adds 2ms (approx) of overhead which might not seem much but when your code is running in 500 microseconds it's almost 4 times.

Other Recommendations

After seeing your code, I realize you're coming from a java background and while in java the getThis() or getThat() is a great way to module your code since we represent our code in classes in java, in python it just causes problems in the readability of the code as mentioned in the PEP 8style guide for python.

I've updated the code below:

import json


def get_contents_from_json(file_path)-> dict:
    """
    Reads the contents of the json file into a dict
    :param file_path:
    :return: A dictionary of all contents in the file.
    """try:
        with open(file_path) as file:
            contents = file.read()
            return json.loads(contents)
    except json.JSONDecodeError:
        print('Error while reading json file')
    except FileNotFoundError:
        print(f'The JSON file was not found at the given path: \n{file_path}')


def write_to_json_file(metadata, timestamp, content, file_path):
    """
    Creates a dict of all the data and then writes it into the file
    :param metadata: The meta data
    :param timestamp: the timestamp
    :param content: the content
    :param file_path: The file in which json needs to be written
    :return: None
    """
    output_dict = dict(metadata=metadata, timestamp=timestamp, content=content)
    with open(file_path, 'w') as outfile:
        json.dump(output_dict, outfile, sort_keys=True, indent=4, ensure_ascii=False)


def main(input_file_path, output_file_path):
    # get a dict from the loaded json
    data = get_contents_from_json(input_file_path)

    # the print() supports multiple args so you don't need multiple print statementsprint('JSON:', json.dumps(data), 'Loaded JSON as dict:', data, sep='\n')

    try:
        # load your data from the dict instead of the methods since it's more pythonic
        metadata = data['metadata']
        timestamp = data['timestamp']
        content = data['content']

        # just cumulating your print statementsprint("Metadata:", metadata, "Timestamp:", timestamp, "Content:", content, sep='\n')

        # write your json to the file.
        write_to_json_file(metadata, timestamp, content, output_file_path)
    except KeyError:
        print('Could not find proper keys to in the provided json')
    except TypeError:
        print('There is something wrong with the loaded data')


if __name__ == '__main__':
    main('stack.json', 'stack-out.json')

Advantages of the above code:

  1. More Modular and hence easily unit testable
  2. Handling of exceptions
  3. Readable
  4. More pythonic
  5. Comments because they are just awesome!

Post a Comment for "Cannot Write Dict Object As Correct Json To File"