Featured image of post Python魔法方法__str__和__repr__深入理解和应用

Python魔法方法__str__和__repr__深入理解和应用

Python 中有不少的魔法方法,我们在阅读源代码过程中,经常会看到__str__方法和__repr__方法,这 2 个方法有什么联系和区别?它们该如何使用?

本文源代码:https://gitee.com/obullxl/PythonCS/tree/master/CS-CY2405

在 Python 中,__str__(self)__repr__(self) 都是非常重要的魔法方法,它们都用于生成对象的字符串,但它们的设计原则和字符串的使用场景并不完全一致:

使用场景不同

__str__(self)方法

场景:当对象转换为字符串时,本方法将被调用(如:str(obj)转换为字符串、print(obj)面向用户输出对象等)。

目的:面向终端用户(如:编程人员、前台展示等),以返回的用户友好的对象的字符串表示内容。该字符串应当易于理解,不一定是对象完整精确描述,它只对终端用户负责。

异常:类如果没有定义__str__方法时,则 Python 会试图把调用__repr__的字符串结果返回给用户。

__repr__(self)方法

场景:本方法定义了对象完整的、精确的、机器可读的字符串表示形式(如:repr(obj)方法调用,IDLE、Jupyter Notebook 等交互式环境中直接输入对象名时的输出内容等)。

目的:面向 Python 内部,是对象合法的表达式字符串,通过该表达式字符串,可通过 eval() 函数执行并重新生成原始对象(即:eval(repr(obj)) == obj应该为True)。

异常:类如果只定义了__str__而没有定义__repr__方法时,则 Python 会试图调用__str__方法来代替,这通常不是一个好的做法。

设计原则不同

从上面使用场景分析,这 2 个方法的设计原则如下:

  • __str__ 面向终端用户查看阅读,所以应尽可能地清晰和简洁,容易理解。

  • __repr__ 面向 Python 内容对象表达,所以应包含足够的信息,并且可以解析为合法的 Python 表达式,且能通过该表达式,通过eval()重新创建对象。

  • 为了遵循 Python 的明确优于隐晦的原则,建议在自定义类中同时定义__str____repr__方法(就像 Java 语言中,同时重写hashCode()equals()方法一样)。如果确实只需要一个,建议优先实现__repr__方法,因为它提供了创建对象所需的所有信息,且可作为__str__方法的备选方法。

禅定:__str____repr__的应用

如下代码样例:PythonCS定义了__str____repr__方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class PythonCS:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return '公众号: ' + self.name

    def __repr__(self):
        return "PythonCS('{}')".format(self.name)


object = PythonCS('Python禅师')
# str调用
print(object)
print(str(object))

# repr调用
ex = repr(object)
print(ex)

# 重新创建对象
object2 = eval(ex)
print(object.name == object2.name)

以上 Python 代码执行结果:

1
2
3
4
公众号: Python禅师
公众号: Python禅师
PythonCS('Python禅师')
True

我的本博客原地址:https://ntopic.cn/p/2024050402


微信公众号:老牛同学

邮箱:obullxl@qq.com
QQ:303630027(老牛啊)
微信:imxulin(奔跑的蜗牛)
支付宝:obullxl@163.com