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__方法则偏向于面向用户的友好展示。在实际编程中,推荐同时定义这两个方法,以确保对象在所有的上下文中都能得到合适的字符串表示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值