Python自定义类中内部函数:__repr__()和__string__()的应用

博客主要对Python类中__repr__和__str__两个内部函数进行小结。介绍了Python中以“下划线”开头定义的变量或函数的特性,单下划线开头的会被子类处理,双下划线开头的对子类隐藏。还说明了__repr__可用于重新创建实例,__str__用于将实例转换为字符串。

我们在定义Python类时,经常会看到比较好的代码中,都有__repr__和__string__,两个内部函数的定义。但是我一直很少关注它们的区别和具体应用场景。稍微做个小结。

1.__foo()__在python中表示__foo__是一个私有private 函数,在CookBook pp254中,解释为,该函数不会被子类的相同名称的函数重载。一般地说,类中以“下划线”开头定义的变量或者函数都是私有变量或者内部函数,区别是:

  1.1 单下划线开始的变量或者函数表示非公有名称,会被子类初始化时处理,也就是说暴露给继承的子类。

  1.2 双下划线开头的变量或函数会对子类隐藏

2.__repr__(),可以被用于obj=eval(repr(obj)),也就说是可以用该函数返回值的字符串文本重新创建该类的实例;而__str__(),是将实例转换为一个字符串。

 

#coding:utf-8
class Test():
    def __init__(self,x,y):
        self.x=x
        self.y=y

    def __repr__(self):
        return 'Test({0.x!r},{0.y!r})'.format(self)   

    def __str__(self):   #convert the instance to string,then print out
        return '({0.x!s},{0.y!s})'.format(self)


#output:
In [4]: from my_repr import Test
In [5]: test=Test
In [6]: test
Out[6]: my_repr.Test
In [7]: test=Test(3,4)  #实例化对象
In [8]: test
Out[8]: Test(3,4)   #返回的是__repr__()中的字符串
In [9]: print(test)  #返回的是__str__()的值
(3,4)
In [10]: tt=eval(repr(test))  #tt是Test类的另一个实例
In [11]: tt
Out[11]: Test(3,4)
In [12]: id(tt)==id(test)
Out[12]: False
In [13]: id(tt)
Out[13]: 2302160271176
In [14]: id(test)
Out[14]: 2302160237176
In [15]: type(test)==type(tt)
Out[15]: True

 

<think>嗯,用户想了解Python中__repr__方法的用法,我得先理清楚这个方法的定义用途。根据引用里的内容,__repr____str__都是用来定义对象字符串表示的,但它们的用途不同。首先,我需要解释__repr__的基本作用,比如官方字符串表示,通常用于调试日志记录。 然后,用户可能需要知道什么时候会触发__repr__方法。比如在交互式环境中直接输入对象,或者使用repr()函数的时候。这时候需要举例子,比如像引用里提到的Person类,当在解释器输入p时,会调用__repr__。 接下来,应该比较__repr____str__的区别,确保用户明白两者的不同应用场景。比如__str__用于用户友好的显示,而__repr__更偏向于开发者,可能需要包含足够的信息来重建对象。根据引用23,可以强调这点,并且指出如果__str__未定义,Python会回退到使用__repr__。 然后,可能需要说明如何正确实现__repr__方法。根据引用4中的例子,通常会返回一个字符串,看起来像是有效的Python表达式,可以用来重新创建对象。比如return f"Person('{self.name}', {self.age})",这样eval(repr(p))就能生成一个新的实例。 另外,用户可能需要示例代码来具体理解。我需要构造一个简单的类,展示__repr__的实现,并演示不同情况下的输出。例如,当打印对象时用__str__,而在交互式环境中显示用__repr__。 还需要提到如果没有定义__repr__,Python会使用默认的实现,通常是类名内存地址,这可能对用户没有帮助,所以自定义__repr__很重要。这一点引用里也有提到,比如引用4中的例子,如果没有定义的话,可能显示类似<__main__.Person object at 0x...>这样的信息。 最后,应该生成相关问题,帮助用户进一步学习,比如__repr__的应用场景,与__str__的区别,如何确保eval可用等。这些问题要基于用户可能产生的疑问,比如他们可能想知道实际开发中哪里会用到,或者如何让__repr__的输出更实用。 检查一下是否覆盖了用户的问题,确保引用的信息准确,并且用中文清晰表达。可能需要避免过于技术化的术语,但保持准确。同时,注意示例代码的正确性,比如使用正确的字符串格式化方法,如f-string,以及符合Python语法。</think>### Python `__repr__` 方法使用说明 `__repr__` 是 Python 中的一个魔术方法,用于定义对象的“官方”字符串表示形式。它主要服务于开发者,常用于调试、日志记录或交互式环境中直接查看对象。以下是详细说明示例: --- #### 1. **基本作用** - **核心用途**:提供对象的无歧义字符串表示,理想情况下应能通过该字符串重新创建对象[^2][^4]。 - **触发场景**: - 在交互式解释器中直接输入对象名称时。 - 调用 `repr(obj)` 函数时。 - 当未定义 `__str__` 方法时,`print(obj)` 会默认调用 `__repr__`[^3]。 --- #### 2. **与 `__str__` 的区别** | 特性 | `__repr__` | `__str__` | |---------------|-------------------------------------|------------------------------------| | **目标用户** | 开发者(调试、日志) | 终端用户(友好显示) | | **返回值要求**| 应尽量明确,可重建对象 | 可读性强,无需严格匹配对象结构 | | **默认行为** | 若未定义,返回类名内存地址(如 `<ClassName object at 0x...>`) | 若未定义,回退到 `__repr__`[^3] | --- #### 3. **实现规范** - **推荐格式**:返回的字符串应类似有效的 Python 表达式,能通过 `eval(repr(obj))` 重建对象。 示例: ```python class Person: def __init__(self, name, age): self.name = name self.age = age def __repr__(self): return f"Person('{self.name}', {self.age})" # 可用于直接创建新对象 ``` 测试效果: ```python p = Person("Alice", 30) print(repr(p)) # 输出:Person('Alice', 30) new_p = eval(repr(p)) # 重建对象 ``` --- #### 4. **实际应用示例** ```python class Vector: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return f"Vector({self.x}, {self.y})" # 明确表示对象结构 def __str__(self): return f"({self.x}, {self.y})" # 简化显示 v = Vector(3, 4) print(v) # 调用 __str__,输出:(3, 4) print(repr(v)) # 调用 __repr__,输出:Vector(3, 4) ``` --- #### 5. **注意事项** - 若未定义 `__repr__`,默认实现可能无法提供有效信息(如 `<Vector object at 0x7f...>`)[^4]。 - 对于容器类(如列表),其元素会调用各自的 `__repr__` 方法。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值