Skip to content

Latest commit

 

History

History
49 lines (29 loc) · 4.75 KB

第1章-python数据模型-4.md

File metadata and controls

49 lines (29 loc) · 4.75 KB

##字符串表示形式 __repr__特殊方法被内置为得到对象的字符串表示形式的repr调用。如果我们没有实现__repr__,向量实例在控制台显示就会如 <Vector object at 0x10e100070>形式。

表达式求值的结果,交互式控制台和调试器会调用repr,正如% r占位符在典型情况下的格式是%运算符,!r 转换符在新的格式字符串语法用于str.format方法。

请注意,在我们的__repr__实现中我们使用%r获得属性的标准表示来显示。这是很好的做法,因为它显示矢量Vector(1, 2)和矢量Vector("1"、"2")间的关键差异--后者不会在这个例子中工作,因为构造函数的参数必须是数字,而不是字符串

通过__repr__返回的字符串应该是明确的,如果可能的话,匹配所必需的源代码,以重新创建所代表的对象。这就是为什么我们选择的代表看起来像调用类的构造函数:例如Vector(3, 4)。

对比__repr____str____str__是通过str()构造函数隐式由打印功能使用的。__str__应该返回一个适合的字符串显示给用户。

如果你只能实现其中的一个特殊方法,选择__repr__,因为当没有自定义__str__可用时,Python调用__repr__作为备用方案。

###tips __repr____str__之间的区别:是由Pythonistas Alex Martelli和Martijn Pieters优秀贡献的StackOverflow问题 ##算数操作符 例1-2实现了两个操作符:+和*,展现__add____mul__的基本用法。请注意,在这两种情况下,该方法创建并返回一个新的实例Vector,不修改任何一个操作数-本身或其他操作数仅仅是读取。这是中缀运算符的预期行为:创建新的对象并没有碰到其操作数。在第13章中,我将有更多的要说。

###tips

作为实现,例1-2允许数乘以一个向量的,但不允许由一个向量乘以一个数,它违反了乘法的交换属性。我们将在13章,用特殊方法__rmul__修补这个问题。

##自定义类型的布尔值 虽然Python有一个bool类型,它却接受一个布尔上下文中的任何对象,如表达控制的if或者while语句,或作为操作数来进行与、或、否操作。Python应用bool(x)确定一个x值是真的或是假的,它总是返回true或false。

默认情况下,除非__bool____len__被实现,用户定义的类的实例被默认认为是真的。基本上,bool(x)调用x.__bool__()和使用其结果。如果__bool__不实现,Python试图调用x.__len__(),如果x.__len__()返回零,则返回false。否则,返回true。

我们的实现__bool__的思路很简单:如果向量的大小为零,它返回false,否则,返回true。我们使用bool(abs(self)) 将大小转换为布尔因为__bool__预计将返回一个布尔值。

注意特殊方法__bool__是如何允许你的对象是与在建在Python标准库的文档类型定义真值章检验规则一致的。

##特殊方法概述

Python语言参考的数据模型列表列出83特殊的方法名,其中47个用于实现算术,位和比较运算符,作为什么是可用的概述,见下表一和下表二 表一 表2

##为何len不是一个方法

这个问题2013年我问核心开发者Raymond Hettinger,他的答案的关键可以用Python之禅的一句话来概括,在纯粹性和实用性之间是倾向实用性的。

在“特殊的方法”第8页描述了为何当x是一个内置类型的一个实例时len(x)跑得很快。没有方法由CPython的内置对象调用:长度仅仅是从C结构体的一个域读取。获取集合中的项的数量是一种常见的操作,必须有效地为字符串,列表,memoryview等基本和多样类型工作。

换句话说,len是不能称其为方法,因为它是作为Python数据模型的一部分,就像abs得到特殊待遇的。但多亏了特殊的方法__len__你也可以用你自己的自定义对象让len工作。这是在内置对象需要高效和语言的一致性之间的公平折衷。再从Python之禅引入一句话来概括:“特殊情况不足以打破规则。” ##本章小结 通过实现特殊的方法,你的对象可以像内置类型一样动作,使得大家公认为是Pythonic的有表现力的编码风格。

对于Python对象的基本要求是提供可用字符串表示自身,一是用于调试和记录,另外是用于呈现给最终用户。这就是为什么特殊方法__repr____str__在数据模型中存在。