Python 3 guide · Updated October 20, 2026
Unicode in Python
Keep text as str while processing it. Encode to bytes for storage or transfer, and decode bytes using their known encoding. Run these examples in Python 3 to see code points, UTF-8 and normalization in practice.
Find a code point with ord() and chr()
Python 3 str values represent Unicode text. ord() takes a single code point and returns its integer value; chr() performs the reverse. A visible symbol can contain several code points, so ord() cannot take every complete emoji sequence.
text = "Aé♥"
print([f"U+{ord(char):04X}" for char in text])
# ['U+0041', 'U+00E9', 'U+2665']
print(chr(0x2665))
# ♥Encode strings and decode bytes with UTF-8
Call encode() when sending text as bytes, and decode() when receiving bytes as text. Use the encoding that actually produced the data; guessing a different codec can produce unreadable text. Invalid input raises an error by default.
text = "café"
data = text.encode("utf-8")
print(data.hex(" "))
# 63 61 66 c3 a9
print(data.decode("utf-8"))
# café
assert data.decode("utf-8") == textDistinguish escape notation from literal text
A Unicode escape inside a normal Python string literal is interpreted by Python. A raw string keeps the backslash characters. Seeing an escape in a representation does not necessarily mean the stored text contains a backslash.
heart = "\u2665"
literal = r"\u2665"
print(heart, len(heart))
# ♥ 1
print(literal, len(literal))
# \u2665 6
assert heart == "♥"Normalize equivalent text before comparing
The same visible accented letter can be represented by a precomposed code point or by a letter plus a combining mark. NFC normalization makes these canonically equivalent examples match. It does not translate languages or remove accents.
import unicodedata
composed = "é"
decomposed = "e\u0301"
print(composed == decomposed)
# False
print(unicodedata.normalize("NFC", decomposed) == composed)
# TrueAvoid common encoding mistakes
- Specify encoding="utf-8" when reading or writing a UTF-8 text file. Confirm the source encoding for older documents.
- Do not use errors="ignore" as a general repair strategy: it silently drops data. Investigate the encoding or handle the error explicitly.
- len() counts code points in a str, rather than visible characters. Combining marks and emoji sequences can contain multiple code points.
- ASCII cannot encode every Unicode character. Replacing or transliterating unsupported characters changes the content.