Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How can I preserve Unicode characters when writing JSON in Python?

Quick answer

Python’s json module preserves Unicode text either way. By default, ensure_ascii=True writes non-ASCII characters as escapes such as \u00e9; ensure_ascii=False writes them directly, such as é. To save readable characters reliably, open the file with encoding='utf-8'. Reopen it the same way, load it with json.load(), and compare the result with the original data. [S1][S2]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

I’m saving text such as café to JSON, but the file shows caf\u00e9. Has Python lost the character, and how do I keep it readable?

Geez

The character has not been lost. Python’s JSON encoder uses ensure_ascii=True by default, so it represents non-ASCII characters with \u escapes. When decoded as JSON, caf\u00e9 and café represent the same string. [S1]

If you want the file itself to show the readable character, pass ensure_ascii=False to json.dump(). Also explicitly open the file with UTF-8 encoding: json.dump() writes text to a text stream, and the file’s encoding determines how that text is stored. [S1][S2] The option changes how non-ASCII characters are represented in the JSON text; it does not change the string value you supplied.

Follow-up question

Can you show both styles and a check that confirms the saved file still loads to the original value?

Geez

Here’s a small example using the same sample data for both files. The first file uses the default escaping; the second writes non-ASCII characters directly. Both are opened explicitly as UTF-8, and each is loaded back and compared with the original object. [S1]

import json

original = {"greeting": "café — こんにちは"}

for filename, use_ascii in (
    ("escaped.json", True),
    ("readable.json", False),
):
    with open(filename, "w", encoding="utf-8") as f:
        json.dump(original, f, ensure_ascii=use_ascii)

    with open(filename, "r", encoding="utf-8") as f:
        loaded = json.load(f)

    assert loaded == original

In escaped.json, the accented and Japanese characters are written using Unicode escape sequences. In readable.json, they appear directly. The assert checks that loading either file reconstructs the original Python object; it does not require the file’s characters to look a particular way. You can open the files in a text editor to inspect the different representations, but the comparison is the check that matters for the decoded data.

Follow-up question

What should I check if the reload comparison fails, or if I see question marks in another program?

Geez

First check that the data you passed to json.dump() contains the expected text, and that you opened the file with encoding='utf-8'. Use the same explicit encoding when reopening it. Then load the file and compare the relevant value—or the whole object—with the original, as in the example. [S1][S2]

If the loaded value matches but another program displays question marks or odd symbols, this example does not establish what that program expects or how it interprets the file. Check that program’s documented encoding settings. The Python documentation explains Python’s JSON serialization and UTF-8 file handling; it does not guarantee how every other application displays the output. [S1][S2] Also remember that ensure_ascii=False does not disable all JSON escaping: required syntax and control characters are still escaped. [S1]

A practical checklist

  • Keep ensure_ascii=True for escaped non-ASCII text, or set ensure_ascii=False for readable characters.

  • Open the output text file with encoding='utf-8'.

  • Reopen the saved file with encoding='utf-8' before calling json.load().

  • Compare the loaded object or text field with the original Python value.

  • If another application displays unexpected characters, check that application’s encoding expectations.

A few more useful answers

Does `ensure_ascii=False` turn off JSON escaping entirely?

No. It writes non-ASCII characters directly, but the encoder still escapes characters required by JSON syntax and control characters. [S1]

Will escaped Unicode change the value I get after loading the JSON?

No. The escaped and readable forms can decode to the same string; loading the file and comparing the result with the original is a practical check. [S1][S2]

Why specify UTF-8 if I use `ensure_ascii=True`?

Explicit UTF-8 makes the text-file encoding clear and avoids relying on a platform’s default encoding. [S1][S2]

Sources

References used for this guide.

  1. [S1] Python 3.14 json — JSON encoder and decoder
    docs.python.org · Checked
  2. [S2] Python 3.15 tutorial: Saving structured data with JSON
    docs.python.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work