首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第 13章 性能测量和大O算法分析
13.1 timeit模块
13.2 cProfile分析器
13.3 大O算法分析
13.4 大O阶
13.4.1 使用书架打比方描述大O阶
13.4.2 大O 测量的是最坏情况
13.5 确定代码的大O 阶
13.5.1 为什么低阶项和系数不重要
13.5.2 大O 分析实例
13.5.3 常见函数调用的大O 阶
13.5.4 一眼看出大O 阶
13.5.5 当n 很小时,大O并不重要,而n通常都很小
第 14章 项目实战
14.1 汉诺塔
14.1.1 汉诺塔输出
14.1.2 汉诺塔源代码
14.1.3 汉诺塔编写代码
14.2 四子棋
14.2.1 四子棋输出
14.2.2 四子棋源代码
14.2.3 四子棋编写代码
第 15章 面向对象编程和类
15.1 拿现实世界打比方:填写表格
15.2 基于类创建对象
15.3 创建一个简单的类——WizCoin
15.3.1 方法__init__()和self
15.3.2 特性
15.3.3 私有特性和私有方法
15.4 函数type()和特性__qualname__
15.5 非OOP 和OOP 的例子:井字棋
15.6 为现实世界设计类是一件难事儿
第 16章 面向对象编程和继承
16.1 继承的原理
16.1.1 重写方法
16.1.2 super()函数
16.1.3 倾向于组合而非继承
16.1.4 继承的缺点
16.2 函数isinstance()和issubclass()
16.3 类方法
16.4 类特性
16.5 静态方法
16.6 何时应该使用类和静态的面向对象特性
16.7 面向对象的行话
16.7.1 封装
16.7.2 多态性
16.8 何时不应该使用继承
16.9 多重继承
16.10 方法解析顺序
第 17章 Python 风格的面向对象编程:属性和魔术方法
17.1 属性
17.1.1 将特性转换为属性
17.1.2 使用setter 验证数据
17.1.3 只读属性
17.1.4 什么时候应该使用属性
17.2 Python 的魔术方法
17.2.1 字符串表示魔术方法
17.2.2 数值魔术方法
17.2.3 反射数值魔术方法
17.2.4 原地魔术方法
17.2.5 比较魔术方法
当前位置:
首页>>
技术小册>>
Python编程轻松进阶(五)
小册名称:Python编程轻松进阶(五)
### 17.2.1 字符串表示魔术方法 在Python中,对象的行为不仅由其定义的方法决定,还常常通过一系列特殊命名的方法(即“魔术方法”)来扩展。这些魔术方法以双下划线(`__`)开头和结尾,为Python对象提供了丰富的内置功能,如初始化、比较、字符串表示等。本章将深入探讨字符串表示相关的魔术方法,特别是`__str__`和`__repr__`,它们在Python编程中扮演着至关重要的角色。 #### 17.2.1.1 理解`__str__`方法 `__str__`方法是一个对象的方法,当使用`str()`函数或`print()`函数打印对象时,Python会自动调用该方法。它应该返回一个字符串,该字符串是对对象状态的“人类可读”表示。良好的`__str__`方法设计能够极大地提高代码的可读性和易用性。 **示例**: ```python 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("Alice", 30) print(person) # 输出: Person(name=Alice, age=30) ``` 在这个例子中,`Person`类通过定义`__str__`方法,使得当`print(person)`被调用时,能够输出一个包含姓名和年龄的字符串,而不是默认的`<__main__.Person object at 0x...>`这样的内存地址表示。 #### 17.2.1.2 深入`__repr__`方法 与`__str__`方法相似,`__repr__`方法也返回一个对象的字符串表示,但其目的和用途有所不同。`__repr__`方法旨在提供一个“官方”的、无歧义的、尽可能详细的字符串表示,使得通过`eval()`函数处理这个字符串时,能够重新创建出原始对象。简而言之,`__repr__`的返回值应该是一个有效的Python表达式。 **示例**: ```python class Person: def __init__(self, name, age): self.name = name self.age = age def __repr__(self): return f"Person(name='{self.name}', age={self.age})" person = Person("Bob", 25) print(repr(person)) # 输出: Person(name='Bob', age=25) # 或者直接使用 repr() 的等价形式 print(person) # 在没有定义 __str__ 的情况下,Python 会调用 __repr__ # 使用 eval 尝试重新创建对象 new_person = eval(repr(person)) print(new_person.name) # 输出: Bob ``` 注意,在上面的例子中,如果同时定义了`__str__`和`__repr__`,`print()`函数会调用`__str__`,而`repr()`函数或在没有`__str__`定义时直接打印对象会调用`__repr__`。 #### 17.2.1.3 `__str__`与`__repr__`的最佳实践 - **`__str__`**:设计用于人类阅读,应提供简洁、易读的信息。在调试时,它帮助开发者快速理解对象的状态。 - **`__repr__`**:设计用于开发者调试,应提供足够的信息以重新创建对象。它应该是一个有效的Python表达式。 - **一致性**:如果`__str__`和`__repr__`都定义了,它们应该尽可能提供一致的信息,但`__repr__`应包含更多细节。 - **性能考虑**:虽然性能通常不是首要考虑因素,但在某些情况下(如大量对象需要频繁转换为字符串表示时),应注意避免在`__str__`或`__repr__`中进行复杂计算或大量内存分配。 #### 17.2.1.4 自定义字符串表示的高级技巧 - **格式化字符串**:利用Python 3.6+引入的f-string(格式化字符串字面量)可以方便地构建复杂的字符串表示。 - **条件逻辑**:在`__str__`或`__repr__`内部使用条件逻辑,根据对象的不同状态返回不同的字符串表示。 - **递归调用**:对于包含嵌套对象的数据结构(如列表、树等),`__str__`或`__repr__`可能需要递归地调用自身以构建完整的字符串表示。 #### 17.2.1.5 实战演练:自定义类的字符串表示 假设我们正在开发一个表示二维向量的类`Vector2D`,我们可以这样定义其`__str__`和`__repr__`方法: ```python class Vector2D: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return f"Vector2D(x={self.x}, y={self.y})" def __repr__(self): return f"Vector2D(x={self.x}, y={self.y})" v = Vector2D(3, 4) print(v) # 输出: Vector2D(x=3, y=4) print(repr(v)) # 输出: Vector2D(x=3, y=4) ``` 在这个例子中,`__str__`和`__repr__`方法返回了相同的字符串表示,但在实际应用中,你可能需要根据具体需求调整它们的行为。 通过本章的学习,你应该对Python中字符串表示的魔术方法`__str__`和`__repr__`有了深入的理解,并掌握了如何为自定义类编写高效、易读的字符串表示方法。这些技巧将极大地提升你的Python编程能力和代码质量。
上一篇:
17.2 Python 的魔术方法
下一篇:
17.2.2 数值魔术方法
该分类下的相关小册推荐:
Python合辑11-闭包函数
剑指Python(磨刀不误砍柴工)
Python甚础Django与爬虫
Python3网络爬虫开发实战(下)
Python合辑9-判断和循环
Python合辑2-字符串常用方法
Python与办公-玩转PDF
Python合辑3-字符串用法深度总结
Python合辑10-函数
机器学习算法原理与实战
Python合辑7-集合、列表与元组
Python机器学习实战