Python中的魔法方法__repr__和__str__详解
引言
当我们直接打印一个python类对象时,得到的通常是类似“<main.ClassName object at 0xmemory_address>”这样一段字符,无法获得对象的具体状态。这个时候我们就可以重新定义/重写对应类的魔术方法__repr__
和__str__
,使得我们在打印对象时能够获得对象的当前状态信息。
1、__repr__
方法
1.1 含义及作用
在Python中,__repr__
方法是一种特殊的方法,全称为 “representation”,即“表示”或“表达”。这个方法用于返回一个对象的“官方”字符串表示形式,主要用于调试和开发目的,使得开发者可以清楚地看到对象的状态。
1.2 示例
下面是一个简单的例子,来说明__repr__
的使用方法:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f'Point(x={self.x}, y={self.y})'
p = Point(1, 2)
# 这个例子中定义了`__repr__`方法
# 输出: Point(x=1, y=2)
print(p)
# 如果没有定义`__repr__`方法,
# 输出可能为:<__main__.Point object at 0x7fecf006e978>
在这个例子中,Point类定义了一个__repr__
方法,当对象p被打印时,就会输出Point(x=1, y=2),这样就清楚的展示了点的位置信息。
2、__str__
方法
2.1 含义及作用
在Python中,__str__
方法也是一种特殊的方法(也称为魔术方法),它定义了如何对对象转换为用户友好的字符串表示形式。当对象被打印(传递给print()函数)或者被转换成字符串类型时(比如使用str(obj)),Python解释器会尝试调用该对象的__str__
方法。
__str__
方法为对象提供了一个简洁、易读的字符串表示,对用户十分友好,以便于开发者和终端用户了解对象的实时状态,通常用于调试和日志记录。
2.2 示例
下面是一个简单的示例,展示了如何定义__str__
方法来描述一个Person类的对象:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name} is {self.age} years old."
# 创建一个Person实例
john = Person('John Doe', 30)
# 打印这个Person实例
print(john) # 输出: John Doe is 30 years old.
# 将对象转换为字符串
person_str = str(john)
print(person_str) # 输出: John Doe is 30 years old.
在这个例子中,__str__
方法返回了一个格式化的字符串,描述了 Person
对象的名字和年龄。当我们将 john
对象打印或转换为字符串时,__str__
方法就会被自动调用,从而返回我们定义的描述性字符串。
如果一个类没有定义__str__
方法,Python解释器会调用内置的__repr__
方法来获取对象的字符串表示。如果也没有定义__repr__
方法,Python解释器会使用默认的字符串表示形式,即返回对象在计算机内存中的实际地址。
3、两种方法的对比
两种方法均由两个下划线开头和结尾,这样的命名方式是 Python 用来标识特殊方法的一种约定。
__repr__
(representation):主要目的是为解释器和开发者提供对象的详细信息,它应该返回一个包含创建此对象所需的所有信息的字符串,理想情况下,该字符串可以用python代码重新创建对象。
__str__
(stringification):主要目的是为对象提供人性化的字符串表示,便于开发者和用户理解对象的状态,它的结果应该简洁直观,易于阅读。
下面举个例子进一步说明两者的不同:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
# 返回一个可以直接被eval()执行的字符串
return f"Person('{self.name}', {self.age})"
def __str__(self):
return f"{self.name} is {self.age} years old."
# 创建一个Person实例
john = Person('John Doe', 30)
# 使用repr函数显示对象的官方字符串表示
print(repr(john)) # 输出: Person('John Doe', 30)
# 使用eval()函数根据`__repr__`提供的字符串重新创建对象
new_john = eval(repr(john))
# 检查新对象是否与原对象具有相同的属性值
print(new_john) # 输出: John Doe is 30 years old.
print(new_john.name, new_john.age) # 输出: John Doe 30
在这个例子中,__repr__方法提供了一个可以用来重新创建Person对象的字符串,该字符串可以通过eval()函数来执行,从而创建一个新的Person实例。而__str__
方法则为Person对象提供了一种人性化的描述。
总的来说,__repr__
方法的目的是尽可能准确地表示对象的状态,以便于开发人员准确了解对象的内部数据。与之相对,__str__
方法则偏向于面向用户的友好展示。在实际编程中,推荐同时定义这两个方法,以确保对象在所有的上下文中都能得到合适的字符串表示。
作者:gemingxuan