Python __str__ 方法
最后修改于 2025 年 4 月 8 日
这份综合指南探讨了 Python 的 __str__ 方法,这是一个负责对象字符串表示的特殊方法。我们将介绍基本用法、格式化、与 __repr__ 的区别以及示例。
基本定义
__str__ 方法返回对象的字符串表示形式。 它由 str() 内置函数和 print() 函数调用,以人类可读的格式显示对象。
关键特征:它必须返回一个字符串对象,目的是可读,并且应该提供简洁的表示。 它与 __repr__ 不同,后者旨在明确和完整。
基本的 __str__ 实现
这是一个简单的类,实现了 __str__ 以提供自定义的字符串表示形式。 这演示了基本的用法模式。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person: {self.name}, {self.age} years old"
p = Person("Alice", 30)
print(p) # Calls __str__ implicitly
print(str(p)) # Explicit call
此示例显示了 __str__ 如何提供可读的字符串格式。 当我们打印对象或调用 str() 时,Python 会调用 __str__ 来获取字符串表示形式。
输出将是 "Person: Alice, 30 years old" (人:爱丽丝,30 岁),这两种情况都表明了 __str__ 如何自定义对象的显示。
__str__ vs __repr__
此示例演示了 __str__ 和 __repr__ 之间的区别,显示了何时调用每个方法以及它们的预期用途。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
p = Point(3, 4)
print(p) # Uses __str__: (3, 4)
print(repr(p)) # Uses __repr__: Point(3, 4)
__repr__ 旨在明确 (适合调试),而 __str__ 旨在可读。 print() 函数使用 __str__,而 REPL 使用 __repr__。
如果未定义 __str__,则 Python 会回退到 __repr__。 最好同时实现两者,以便在不同的上下文中保持清晰。
使用 __str__ 格式化
__str__ 方法可以包含复杂的格式化,以表格形式显示对象数据,如下所示。
class Product:
def __init__(self, name, price, quantity):
self.name = name
self.price = price
self.quantity = quantity
def __str__(self):
header = f"{'Name':<15}{'Price':>10}{'Quantity':>12}"
divider = "-" * 37
row = f"{self.name:<15}${self.price:>9.2f}{self.quantity:>12}"
return f"{header}\n{divider}\n{row}"
item = Product("Laptop", 1299.99, 5)
print(item)
此实现创建了一个具有对齐列的格式化表格状输出。 字符串格式化微语言用于控制间距和小数位数,以获得专业的输出效果。
输出将显示标题行、分隔线和整齐对齐的产品数据,演示了 __str__ 如何增强可读性。
继承中的 __str__
使用继承时,可以扩展 __str__ 以包含来自父类和子类的信息,如本例所示。
class Animal:
def __init__(self, species):
self.species = species
def __str__(self):
return f"Species: {self.species}"
class Dog(Animal):
def __init__(self, name, breed):
super().__init__("Canine")
self.name = name
self.breed = breed
def __str__(self):
return f"{super().__str__()}, Name: {self.name}, Breed: {self.breed}"
dog = Dog("Buddy", "Golden Retriever")
print(dog)
子类的 __str__ 使用 super() 调用父类的版本,然后添加自己的信息。 这创建了一个完整的字符串表示形式,结合了类层次结构的两个级别。
输出将是 "Species: Canine, Name: Buddy, Breed: Golden Retriever" (物种:犬科,名称:巴迪,品种:金毛寻回犬),显示了继承链如何构建全面的字符串表示形式。
动态 __str__ 内容
__str__ 可以根据对象的当前状态生成动态内容,如这个基于时间的问候示例所示。
import datetime
class Greeter:
def __init__(self, name):
self.name = name
def __str__(self):
hour = datetime.datetime.now().hour
if hour < 12:
time_of_day = "morning"
elif hour < 18:
time_of_day = "afternoon"
else:
time_of_day = "evening"
return f"Good {time_of_day}, {self.name}!"
greeting = Greeter("Alice")
print(greeting) # Changes based on current time
此 __str__ 实现检查当前时间并生成适当的问候消息。 字符串表示形式会根据调用时间动态变化。
这演示了 __str__ 如何合并运行时信息以创建上下文感知的表示形式,从而使对象更具交互性。
最佳实践
- 保持可读性:__str__ 应该优先考虑人类可读性
- 包含关键信息: 专注于最重要的属性
- 返回字符串: 必须返回一个字符串对象,而不是打印
- 考虑性能: 复杂的格式化可能会影响性能
- 同时实现 __repr__: 始终提供两种字符串方法
资料来源
作者
列出所有 Python 教程。