The ascii() built-in function returns a string containing a printable representation of an object, escaping non-ASCII characters using \x, \u, or \U escapes.
7-Bit Clean Representations: In Python 3, standard repr() preserves Unicode characters in their native visual form. The ascii() function operates similarly to Python 2's repr(), ensuring that accented characters, symbols, and emojis are converted into 7-bit ASCII-safe escape sequences. To convert code point numbers directly to characters, see chr(), or get integer code points with ord().
The ascii() function accepts a single object and returns a 7-bit ASCII string representation:
# Formal syntax of built-in ascii()
printable_ascii_str = ascii(object)
| Parameter | Type | Default | Description & Operational Rule |
|---|---|---|---|
object |
Any |
Required | The target object, string, collection, or instance to convert into an ASCII-escaped representation. |
| Return | str |
N/A | A string representation where all non-ASCII characters are escaped via \x, \u, or \U. |
| Escape Format | Unicode Code Point Range | Example Character | Escaped Output |
|---|---|---|---|
\xNN |
U+0080 to U+00FF (Latin-1 Supplement) | ñ (U+00F1) |
'\xf1' |
\uNNNN |
U+0100 to U+FFFF (Basic Multilingual Plane) | € (U+20AC) |
'\u20ac' |
\UNNNNNNNN |
U+10000+ (Supplementary Planes / Emojis) | 🚀 (U+1F680) |
'\U0001f680' |
Passing strings containing accents, umlauts, or currency symbols converts each non-ASCII character into an escape sequence:
# 1. Escaping accented characters, symbols, and non-ASCII text
text1 = 'Café'
text2 = 'jalapeño'
text3 = 'plus2net_€'
print("ascii(Café): ", ascii(text1))
print("ascii(jalapeño): ", ascii(text2))
print("ascii(plus2net_€):", ascii(text3))Terminal Output:
ascii(Café): 'Caf\xe9'
ascii(jalapeño): 'jalape\xf1o'
ascii(plus2net_€): 'plus2net_\u20ac'
In Python 3, both str() and repr() keep Unicode characters visually unescaped. ascii() is unique because it forces full 7-bit escaping:
# 2. Comparative demonstration: str() vs. repr() vs. ascii()
greeting = "Bonjour, café! 🚀"
print("str() output: ", str(greeting))
print("repr() output: ", repr(greeting))
print("ascii() output:", ascii(greeting))Terminal Output:
str() output: Bonjour, café! 🚀
repr() output: 'Bonjour, café! 🚀'
ascii() output: 'Bonjour, caf\xe9! \U0001f680'
When applied to container data structures, ascii() recursively traverses the collection, escaping every non-ASCII key or element:
# 3. Applying ascii() across collections (lists, tuples, dicts, sets)
student_records = [
{"name": "André", "country": "Français"},
{"name": "Niño", "hobby": "Piñata"}
]
print("Escaped list of dictionaries:")
print(ascii(student_records))Terminal Output:
Escaped list of dictionaries:
[{'name': 'Andr\xe9', 'country': 'Fran\xe7ais'}, {'name': 'Ni\xf1o', 'hobby': 'Pi\xf1ata'}]
When ascii() is called on a custom class instance, it invokes the object's __repr__() method first and then replaces any non-ASCII characters with escape sequences:
# 4. Custom classes implementing __repr__() with ascii()
class ProductItem:
def __init__(self, title, currency_symbol, price):
self.title = title
self.currency_symbol = currency_symbol
self.price = price
def __repr__(self):
return f"{self.title} ({self.currency_symbol}{self.price})"
item = ProductItem("Gourmet Café", "€", 4.50)
print("Standard repr: ", repr(item))
print("ascii() output:", ascii(item))Terminal Output:
Standard repr: Gourmet Café (€4.5)
ascii() output: Gourmet Caf\xe9 (\u20ac4.5)
Because ascii() generates syntactically valid Python escape literals, passing the escaped string into eval() cleanly reconstructs the original Unicode string:
# 5. Round-tripping and reversible evaluation
original = "München Überraschung"
escaped = ascii(original)
print("Escaped string: ", escaped)
# eval() safely recovers the exact original unicode string
restored = eval(escaped)
print("Restored string:", restored)
print("Integrity check:", restored == original)Terminal Output:
Escaped string: 'M\xfcnchen \xdcberraschung'
Restored string: München Überraschung
Integrity check: True
Legacy logging aggregators and metric collectors can corrupt or choke on multi-byte UTF-8 sequences. Sanitizing log records with ascii() guarantees 7-bit safety:
# 6. Production Recipe: ASCII-Safe Telemetry & Log Sanitizer
def sanitize_log_message(event_data: dict) -> str:
"""Converts any dictionary containing unicode/emojis to a 7-bit clean log line."""
safe_entries = []
for key, value in event_data.items():
# Ensure key and value are strictly 7-bit ASCII safe
safe_k = ascii(key).strip("'\"")
safe_v = ascii(value).strip("'\"")
safe_entries.append(f"{safe_k}={safe_v}")
return " | ".join(safe_entries)
event = {
"user": "Renée_99",
"action": "purchased_té",
"device": "iPhone_📱",
"city": "São_Paulo"
}
print("Clean log entry:")
print(sanitize_log_message(event))Terminal Output:
Clean log entry:
user=Ren\xe9e_99 | action=purchased_t\xe9 | device=iPhone_\U0001f4f1 | city=S\xe3o_Paulo
Understanding the exact distinction between ascii(), ord(), and str.encode() prevents type conversion bugs:
# 7. Common traps: ascii() vs. ord() vs. encode()
# Trap 1: ascii() returns a str with escape sequences; ord() returns an integer
char = 'é'
print("ascii() output (str):", ascii(char))
print("ord() output (int): ", ord(char))
# Trap 2: encode('ascii', 'backslashreplace') returns bytes, NOT str
byte_version = char.encode('ascii', 'backslashreplace')
print("encode() output: ", byte_version, "| type:", type(byte_version).__name__)Terminal Output:
ascii() output (str): '\xe9'
ord() output (int): 233
encode() output: b'\\xe9' | type: bytes
Practice non-ASCII character escaping, collection formatting, and log sanitization in our interactive companion Jupyter Notebook:
Explore interactive code cells, compare ascii() vs. repr(), test custom class implementations, and run self-validating assertions.
Run these unit checks directly in Python or your local environment to verify ascii() mechanics:
# 8. Self-verifying unit test suite for ascii()
# Test 1: Basic Latin-1 escaping
assert ascii('Café') == "'Caf\\xe9'"
# Test 2: BMP Unicode escaping (Euro symbol)
assert ascii('€') == "'\\u20ac'"
# Test 3: SMP Unicode escaping (Emoji)
assert ascii('🚀') == "'\\U0001f680'"
# Test 4: Reversible round-trip with eval()
sample_text = "Naïve Façade"
assert eval(ascii(sample_text)) == sample_text
# Test 5: Plain ASCII remains unescaped
assert ascii("plus2net_123") == "'plus2net_123'"
print("All ascii() unit assertions successfully verified!")Terminal Output:
All ascii() unit assertions successfully verified!
In Python 3, repr() displays Unicode characters natively (e.g. 'café'). ascii() replaces any non-ASCII characters with escape sequences (e.g. 'caf\xe9').
ascii() returns a standard Python str containing 7-bit ASCII characters, not a bytes object.
Because the output of ascii() is a valid Python string literal, calling eval() on it restores the original Unicode string.
Characters outside the Basic Multilingual Plane (U+10000 and above, such as emojis) use the 8-digit \UNNNNNNNN escape format.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.