在 Python 中,__str__
和 __repr__
是两个非常重要的特殊方法,它们用于定义对象的字符串表示形式。虽然这两个方法看起来相似,但它们的作用和使用场景却有所不同。今天我们就来深入探讨一下这两个方法,看看它们究竟有什么不同,以及如何在实际开发中正确使用它们。
1. __str__
方法
__str__
方法用于返回一个对象的“非正式”或“可读”字符串表示形式。当你使用 print()
函数打印一个对象时,Python 会调用该对象的 __str__
方法。如果对象没有定义 __str__
方法,Python 会退而求其次,调用 __repr__
方法。
示例 1: 定义 __str__
方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
# 创建一个 Person 对象
person = Person("Alice", 30)
# 打印对象
print(person) # 输出: Person(name=Alice, age=30)
在这个例子中,我们定义了一个 Person
类,并实现了 __str__
方法。当我们使用 print()
函数打印 person
对象时,输出的是我们自定义的字符串表示形式。
2. __repr__
方法
__repr__
方法用于返回一个对象的“正式”或“调试”字符串表示形式。通常,__repr__
的输出应该足够详细,以便能够从字符串表示形式重新创建对象。当你在交互式解释器中直接输入一个对象时,Python 会调用该对象的 __repr__
方法。
示例 2: 定义 __repr__
方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person(name={self.name!r}, age={self.age!r})"
# 创建一个 Person 对象
person = Person("Alice", 30)
# 在交互式解释器中直接输入对象
person # 输出: Person(name='Alice', age=30)
在这个例子中,我们定义了 __repr__
方法。注意,我们使用了 !r
转换标志,它会调用对象的 __repr__
方法,而不是 __str__
方法。这样可以确保输出的字符串是可复制和粘贴的,从而可以在 Python 解释器中重新创建对象。
3. __str__
和 __repr__
的区别
用途:
__str__
:用于生成可读性强的字符串表示形式,适合用户查看。__repr__
:用于生成详细的字符串表示形式,适合调试和开发人员查看。默认行为:
如果没有定义 __str__
方法,Python 会使用__repr__
方法。如果没有定义 __repr__
方法,Python 会使用默认的object.__repr__
方法,返回一个包含对象内存地址的字符串。
示例 3: 比较 __str__
和 __repr__
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
def __repr__(self):
return f"Person(name={self.name!r}, age={self.age!r})"
# 创建一个 Person 对象
person = Person("Alice", 30)
# 使用 print() 函数
print(person) # 输出: Person(name=Alice, age=30)
# 在交互式解释器中直接输入对象
person # 输出: Person(name='Alice', age=30)
在这个例子中,我们同时定义了 __str__
和 __repr__
方法。可以看到,print()
函数调用了 __str__
方法,而交互式解释器直接输入对象时调用了 __repr__
方法。
4. 实战案例:日志记录
在实际开发中,__str__
和 __repr__
方法经常用于日志记录。一个好的日志记录系统需要能够输出详细的信息,以便于调试和问题排查。下面我们来看一个具体的例子。
示例 4: 日志记录
假设我们有一个 Order
类,用于表示订单。我们需要在日志中记录订单的详细信息。
import logging
class Order:
def __init__(self, order_id, customer_name, items):
self.order_id = order_id
self.customer_name = customer_name
self.items = items
def __str__(self):
return f"Order ID: {self.order_id}, Customer: {self.customer_name}"
def __repr__(self):
return (f"Order(order_id={self.order_id!r}, "
f"customer_name={self.customer_name!r}, "
f"items={self.items!r})")
# 配置日志记录
logging.basicConfig(level=logging.DEBUG)
# 创建一个 Order 对象
order = Order(12345, "John Doe", ["Apple", "Banana"])
# 记录日志
logging.debug(f"Processing order: {order!r}")
logging.info(f"Order details: {order}")
# 输出:
# DEBUG:root:Processing order: Order(order_id=12345, customer_name='John Doe', items=['Apple', 'Banana'])
# INFO:root:Order details: Order ID: 12345, Customer: John Doe
在这个例子中,我们定义了一个 Order
类,并实现了 __str__
和 __repr__
方法。我们在日志记录中分别使用了 __repr__
和 __str__
方法,以确保日志信息既详细又可读。
总结
本文介绍了 Python 中 __str__
和 __repr__
方法的区别和使用场景。__str__
方法用于生成可读性强的字符串表示形式,适合用户查看;而 __repr__
方法用于生成详细的字符串表示形式,适合调试和开发人员查看。通过实际的代码示例,我们展示了如何在类中实现这两个方法,并在日志记录中合理使用它们。
好了,今天的分享就到这里了,我们下期见。如果本文对你有帮助,请动动你可爱的小手指点赞、转发、在看吧!
付费合集推荐
文末福利
公众号消息窗口回复“编程资料”,获取Python编程、人工智能、爬虫等100+本精品电子书。