对象表示形式
每门面向对象的语言至少都有一种获取对象的字符串表示形式的标准方式。Python 提供了两种方式
repr()
以便于开发者理解的方式返回对象字符串表示形式
str()
以便于用户理解的方式返回对象的字符串表示形式。
正如你所知,我们要实现 __repr__ 和 __str__ 特殊方法,为 repr()和 str() 提供支持。
再谈向量类
为了说明用于生成对象表示形式的众多方法,我们将使用一个Vector2d 类。这一节和接下来的几节会不断实现这个类。我们期望 Vector2d 实例具有的基本行为如下所示。
Vector2d 实例有多种表示形式
>>> v1 = Vector2d(3, 4)
>>> print(v1.x, v1.y) #Vector2d实例的分量可以直接通过属性访问
3.0 4.0
>>> x, y = v1 #Vector2d实例可以拆包成变量元祖
>>> x, y
(3.0, 4.0)
>>> v1 #repr函数调用Vector2d实例,得到的结果类似于构建实例的源码
Vector2d(3.0, 4.0)
>>> v1_clone = eval(repr(v1)) #这里使用eval函数,表明repr函数调用Vector2d实例得到的是对构造方法的准确表述
>>> v1 == v1_clone #Vector2d实例支持使用==比较;这样便于测试
True
>>> print(v1) #print函数会调用str函数,对Vector2d来说,输出的是一个有序对
(3.0, 4.0)
>>> octets = bytes(v1) #bytes函数会调用__bytes__方法,生成实例的二进制表示形式
>>> octets
b'd\\x00\\x00\\x00\\x00\\x00\\x00\\x08@\\x00\\x00\\x00\\x00\\x00\\x00\\x10@'
>>> abs(v1) #abs函数会调用__abs__方法,返回Vector2d实例的模
5.0
>>> bool(v1), bool(Vector2d(0, 0)) #bool函数会调用__bool__方法,如果Vector2d实例的模为零,则返回False,否则返回True
vector2d_v0.py实现的方式
from array import array
import math class Vector2d:
typecode = 'd' #类属性 def __init__(self, x, y): #构造函数,实例化接收两个参数,x和y,转成float类型
self.x = float(x)
self.y = float(y) def __iter__(self): #支持迭代,也就是支持外面的拆包操作 例如,x, y = my_vector
return (i for i in (self.x, self.y)) def __repr__(self): #__repr__ 方法使用 {!r} 获取各个分量的表示形式,然后插值,
class_name = type(self).__name__ # 构成一个字符串;因为 Vector2d 实例是可迭代的对象,所以
return '{}({!r}, {!r})'.format(class_name, *self) # *self 会把x 和 y 分量提供给 format 函数 def __str__(self): #从可迭代的 Vector2d 实例中可以轻松地得到一个元组,显示为一个有序对
return str(tuple(self)) def __bytes__(self):
return (bytes([ord(self.typecode)])+ #为了生成字节序列,我们把 typecode 转换成字节序列
bytes(array(self.typecode, self))) #迭代 Vector2d 实例,得到一个数组,再把数组转换成字节序列 def __eq__(self, other): #为了快速比较所有分量,在操作数中构建元组
return tuple(self) == tuple(other) def __abs__(self): #模是 x 和 y 分量构成的直角三角形的斜边长
return math.hypot(self.x, self.y) def __bool__(self): #__bool__ 方法使用 abs(self) 计算模,然后把结果转换成布尔值,因此,0.0 是 False,非零值是 True。
return bool(abs(self))
备选构造方法
我们可以把 Vector2d 实例转换成字节序列了;同理,也应该能从字节序列转换成 Vector2d 实例。使用之前我们用过得array.array 有个类方法 .frombytes。