Python
UTF-8
string conversion
encoding
programming教程

How to convert a string to utf-8 in Python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Python 3, text and encoded bytes are different things. That matters when people say they want to "convert a string to UTF-8," because a Python str already represents Unicode text, while UTF-8 is a byte encoding used when you store or transmit that text.

Understand str versus bytes

The most important concept is that UTF-8 is not another flavor of Python string. A Python str is decoded text. To get UTF-8 data, you encode the text into a bytes object.

python
1text = "cafe and cafe\u0301"
2utf8_bytes = text.encode("utf-8")
3
4print(type(text))
5print(type(utf8_bytes))
6print(utf8_bytes)

Typical output looks like this:

text
<class 'str'>
<class 'bytes'>
b'cafe and cafe\xcc\x81'

If your goal is to send text over a socket, write it to a file, or store it in a system that expects bytes, this is the correct conversion.

Decode bytes back into text when needed

If you already have UTF-8 bytes and want a Python string, you do the opposite operation with decode.

python
1data = b"\xe4\xbd\xa0\xe5\xa5\xbd"
2text = data.decode("utf-8")
3
4print(text)

This prints the decoded Unicode text. Keeping the distinction clear prevents a lot of encoding confusion:

  • 'str.encode(...) converts text to bytes'
  • 'bytes.decode(...) converts bytes to text'

Handle file input and output explicitly

A common place to work with UTF-8 is file I/O. The cleanest approach is usually to let Python handle the encoding at the file boundary.

python
1message = "Hello, 你好, bonjour"
2
3with open("message.txt", "w", encoding="utf-8") as file:
4    file.write(message)
5
6with open("message.txt", "r", encoding="utf-8") as file:
7    loaded = file.read()
8
9print(loaded)

This is often better than manually encoding and decoding unless you truly need raw bytes. It also makes the code's intent obvious to the next person reading it.

Encoding is different from Unicode normalization

Sometimes text "looks wrong" even after correct UTF-8 encoding because the issue is not encoding at all. Some characters can be represented in more than one Unicode form, so normalization may matter too.

python
1import unicodedata
2
3text = "cafe\u0301"
4normalized = unicodedata.normalize("NFC", text)
5
6print(text.encode("utf-8"))
7print(normalized.encode("utf-8"))

This is not a UTF-8 conversion step by itself, but it is an important distinction when apparently equivalent strings compare differently.

Converting from another encoding

Sometimes the real problem is not "convert a string to UTF-8" but "I received bytes in the wrong encoding and need UTF-8 output." In that case, decode using the original encoding first, then encode as UTF-8.

python
1latin1_bytes = b"caf\xe9"
2text = latin1_bytes.decode("latin-1")
3utf8_bytes = text.encode("utf-8")
4
5print(text)
6print(utf8_bytes)

That two-step process matters because Python cannot correctly turn arbitrary bytes into UTF-8 unless it knows what those bytes currently mean.

Use error handling deliberately

Real input is messy. You may encounter bytes that cannot be decoded with the encoding you expected. Python lets you choose how strict to be.

python
1bad_data = b"hello\xffworld"
2
3decoded = bad_data.decode("utf-8", errors="replace")
4print(decoded)

Common errors modes include:

  • 'strict to raise an exception'
  • 'replace to substitute invalid data'
  • 'ignore to skip bad bytes'

For debugging and data quality, strict is often best. For user-facing pipelines where partial recovery is acceptable, replace can be practical.

Common Pitfalls

The biggest pitfall is trying to call encode on bytes or decode on text without checking the current type first. If you double-encode or double-decode data, the result is either an exception or corrupted text.

Another common problem is assuming every text file is UTF-8. Many systems still emit Latin-1, Windows-1252, Shift-JIS, or other encodings. When the source bytes are not really UTF-8, calling .decode("utf-8") will fail or produce replacement characters.

It is also easy to confuse display issues with storage issues. A terminal or editor may render characters incorrectly even when the data itself is valid UTF-8. In that case, the problem is the display environment, not the Python code.

Finally, do not "convert a string to UTF-8" unless you actually need bytes. Inside most Python 3 application code, keeping values as str for as long as possible is simpler and safer.

Summary

  • In Python 3, str is Unicode text and UTF-8 is a byte encoding.
  • Use text.encode("utf-8") to get UTF-8 bytes from a string.
  • Use data.decode("utf-8") to turn UTF-8 bytes into a string.
  • Specify encoding="utf-8" at file boundaries to keep I/O explicit.
  • Decode from the original encoding first when incoming bytes are not already UTF-8.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.