The NameError: name 'unicode' is not defined is a clear indication that you are running code written for Python 2 in a Python 3 environment. In Python 2, unicode was a distinct built-in type representing Unicode text strings. In Python 3, this type was renamed to str, and the original str type (which represented byte strings in Python 2) was essentially replaced by the bytes type.
This guide explains this fundamental Python 2-to-3 change and shows how to update your code by replacing unicode with the appropriate Python 3 equivalent, usually str.
Understanding the Error: Python 2 unicode vs. Python 3 str
The core difference lies in how Python versions handle text and binary data:
- Python 2:
str: Represented sequences of bytes (8-bit strings). Often used for text, but could lead to encoding issues if non-ASCII characters were involved without proper handling.unicode: Represented sequences of Unicode characters (abstract text). Created usingu'...'literals or theunicode()function for decoding byte strings. This was the correct type for handling international text.
- Python 3:
str: Represents sequences of Unicode characters (like Python 2'sunicode). This is the standard type for all text.u'...'literals are no longer needed or used.bytes: Represents sequences of bytes (binary data). Created usingb'...'literals or by encoding strings (my_str.encode()).- The name
unicodeis gone as a built-in type or function.
The NameError occurs because Python 3 simply does not have a built-in object named unicode.
Cause: Using the Python 2 unicode Name in Python 3
You are running Python 3 code that still uses the name unicode as if it were the Python 2 type or function.
try:
text = unicode("some string", "utf-8") # Example usage from Python 2
print(text)
except NameError as e:
print(e)
try:
is_text = isinstance("hello", unicode)
print(is_text)
except NameError as e:
print(e)Solution 1: Replace unicode() with str() (Recommended)
The direct fix for Python 3 code is to replace occurrences of the name unicode with str.
- If the original code used
unicode(byte_string, encoding)to decode bytes, replace it withstr(byte_string, encoding)or, more commonly,byte_string.decode(encoding). - If the original code used
unicode(object)to get a text representation, replace it withstr(object). - If the original code used
isinstance(obj, unicode)to check for text, replace it withisinstance(obj, str).
byte_data = b'hello bytes'
encoding = 'utf-8'
text1 = str(byte_data, encoding)
text2 = byte_data.decode(encoding)
print(f"Decoded using str(): '{text1}' (Type: {type(text1)})")
print(f"Decoded using decode(): '{text2}' (Type: {type(text2)})")
number = 123
text_num = str(number)
print(f"Number as string: '{text_num}' (Type: {type(text_num)})")
my_string = "this is text"
is_text = isinstance(my_string, str)
print(f"Is '{my_string}' a string (str)? {is_text}") Solution 2: Create a unicode Alias for Compatibility (Less Common)
If you are managing code that needs to run on both Python 2 and Python 3 (a "cross-compatible" codebase), you might see or use a compatibility shim that defines unicode as an alias for str when running in Python 3.
import sys
if sys.version_info[0] >= 3:
unicode = str
else:
pass
some_text = "hello"
if isinstance(some_text, unicode): # Uses the alias in Python 3
print(f"\n'{some_text}' is considered unicode/str.")
number = 456
text_version = unicode(number) # Uses the alias in Python 3
print(f"Number converted via alias: '{text_version}' (Type: {type(text_version)})")Python 3 Text (str) vs. Binary Data (bytes)
It's essential to understand the clear distinction in Python 3:
str: For representing text. All strings are sequences of Unicode characters. Literals are written with'...'or"...".text_example = "résumé" # Contains Unicode characters print(f"String: {text_example} (Type: {type(text_example)})")bytes: For representing binary data (sequences of raw bytes, 0-255). Literals are written withb'...'orb"...". Bytes literals can only contain ASCII-compatible characters directly.bytes_example = b'raw data' print(f"Bytes: {bytes_example} (Type: {type(bytes_example)})")
Encoding (str to bytes)
Converting text (str) to binary data (bytes) requires encoding. You specify an encoding scheme (like 'utf-8').
text_to_encode = "résumé"
utf8_bytes = text_to_encode.encode('utf-8')
print(f"'{text_to_encode}' encoded to UTF-8: {utf8_bytes}")Decoding (bytes to str)
Converting binary data (bytes) back to text (str) requires decoding using the same encoding scheme it was encoded with.
utf8_bytes = b'r\xc3\xa9sum\xc3\xa9'
decoded_text = utf8_bytes.decode('utf-8')
print(f"{utf8_bytes} decoded from UTF-8: '{decoded_text}'")Conclusion
The NameError: name 'unicode' is not defined is a definitive sign of running Python 2 code, or code written with Python 2 idioms, in a Python 3 environment.
The primary solution is to replace all uses of the name unicode with the Python 3 equivalent, which is almost always str.
- Replace
unicode()calls used for decoding with.decode()orstr(bytes, encoding). - Replace
unicode()calls used for string conversion withstr(). - Replace
isinstance(..., unicode)checks withisinstance(..., str).
Understanding the fundamental shift from Python 2's str/unicode model to Python 3's bytes/str model is key to correctly handling text and binary data and resolving this NameError. Avoid compatibility shims unless absolutely necessary for cross-version support.