以下是Python中str()与repr()函数的详细对比解析,专为初学者设计,结合实用场景和记忆技巧:
一、核心区别速记表
特性 | str() | repr() |
目标 | 用户友好显示 | 开发者调试/重建对象 |
返回值 | 可读性优先(如无引号) | 精确性优先(保留语法标记) |
自动调用场景 | print()、str.format() | 交互式解释器、日志调试 |
自定义方法 | __str__() | __repr__() |
二、直观对比示例
1. 字符串处理
s = "Hello\nWorld"
print(str(s))
# 输出显示(用户友好):
# Hello
# World
print(repr(s))
# 输出显示(开发者视角):
# 'Hello\nWorld' (显示换行符和引号)2. 特殊字符
tab_char = "\t"
print(f"str: {str(tab_char)}") # 输出: str: (显示制表符空白)
print(f"repr: {repr(tab_char)}") # 输出: repr: '\t' (显示转义字符)3. 数值类型
num = 3.1415926
print(str(num)) # 输出: 3.1415926 (简洁显示)
print(repr(num)) # 输出: 3.1415926 (与str相同,因数值无歧义)三、何时用哪个?
使用str()的场景:
- 面向终端用户的输出(如网页/APP界面)
- 文件写入(非调试用途)
- 字符串拼接:
name = "Alice"
age = 25
print("Name: " + str(name) + ", Age: " + str(age))使用repr()的场景:
- 调试日志记录(保留原始数据形态)
- 开发时打印变量检查:
data = {"user": "admin", "psw": "123\\x45"}
print(f"DEBUG: {repr(data)}") # 显示真实存储内容自定义类的调试信息:
class Product:
def __repr__(self):
return f"Product(name={self.name!r})" # !r表示调用repr四、自定义类的实践
1. 标准实现模板
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Student {self.name} ({self.age}岁)"
def __repr__(self):
return f"Student(name={repr(self.name)}, age={repr(self.age)})"
# 测试输出
s = Student("李华", 18)
print(str(s)) # 输出: Student 李华 (18岁)
print(repr(s))) # 输出: Student(name='李华', age=18)2. 快捷实现技巧
若未定义__str__,Python会回退到使用__repr__:
class Book:
def __repr__(self):
return f"Book({repr(self.title)})" # 同时服务于str()和repr()
b = Book("Python入门")
print(str(b)) # 输出: Book('Python入门')五、特殊语法技巧
1. 格式化字符串中的!r
name = "Alice"
print(f"Raw name: {name!r}") # 等价于 repr(name)
# 输出: Raw name: 'Alice'2. 容器中的自动调用
mixed = ["text", "\n", 123]
print(str(mixed)) # 输出: ['text', '\n', 123] (实际调用元素的__repr__!)六、常见误区解答
Q1: 为什么print(list)调用的是元素的__repr__?
- 为保证容器内元素的精确显示(如区分字符串"1"和数字1)
Q2: 数值类型的str和repr为何相同?
x = 3.0
print(str(x), repr(x)) # 输出: 3.0 3.0→ 因浮点数的字符串表示本身无歧义,无需额外标记
Q3: 如何强制显示str()效果?
data = {"key": "value"}
print("%s" % data) # 调用str()
print("%r" % data) # 调用repr()七、记忆口诀
"String for Show,
Repr for Report and Recreate."
(str()用于展示,repr()用于报告和重建)
八、实战建议
基础阶段:
- 输出用户内容用str()
- 调试变量用repr()
进阶开发:
- 所有自定义类实现__repr__()
- 按需实现__str__()
日志规范:
logging.debug("Received: %r", raw_data) # 使用repr保留细节 