流畅的 Python(4):Python 数据模型 1.2.1

阅读数:12 2019 年 11 月 20 日 16:49

流畅的Python(4):Python 数据模型 1.2.1

内容简介
本书致力于帮助 Python 开发人员挖掘这门语言及相关程序库的优秀特性,避免重复劳动,同时写出简洁、流畅、易读、易维护,并且具有地道 Python 风格的代码。本书尤其深入探讨了 Python 语言的高级用法,涵盖数据结构、Python 风格的对象、并行与并发,以及元编程等不同的方面。

(模拟数值类型)

利用特殊方法,可以让自定义对象通过加号“+”(或是别的运算符)进行运算。第 13 章对此有详细的介绍,现在只是借用这个例子来展示特殊方法的使用。

我们来实现一个二维向量(vector)类,这里的向量就是欧几里得几何中常用的概念,常在数学和物理中使用的那个(见图 1-1)。

图 1-1:一个二维向量加法的例子,Vector(2,4) + Vextor(2,1) = Vector(4,5)

Python 内置的 complex 类可以用来表示二维向量,但我们这个自定义的类可以扩展到 n 维向量,详见第 14 章。

为了给这个类设计 API,我们先写个模拟的控制台会话来做 doctest。下面这一段代码就是图 1-1 所示的向量加法:

>>> v1 = Vector(2, 4)
>>> v2 = Vector(2, 1)
>>> v1 + v2
Vector(4, 5)

注意其中的 + 运算符所得到的结果也是一个向量,而且结果能被控制台友好地打印出来。

abs 是一个内置函数,如果输入是整数或者浮点数,它返回的是输入值的绝对值;如果输入是复数(complex number),那么返回这个复数的模。为了保持一致性,我们的 API 在碰到 abs 函数的时候,也应该返回该向量的模:

>>> v = Vector(3, 4)
>>> abs(v)
5.0

我们还可以利用 * 运算符来实现向量的标量乘法(即向量与数的乘法,得到的结果向量的方向与原向量一致 1,模变大):

1 如果向量与负数相乘,得到的结果向量的方向与原向量相反。——编者注

>>> v * 3
Vector(9, 12)
>>> abs(v * 3)
15.0

示例 1-2 包含了一个 Vector 类的实现,上面提到的操作在代码里是用这些特殊方法实现的:__repr____abs____add____mul__

示例 1-2 一个简单的二维向量类

from math import hypot

class Vector:

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Vector(%r, %r)' % (self.x, self.y)

    def __abs__(self):
        return hypot(self.x, self.y)

    def __bool__(self):
        return bool(abs(self))

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)

    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)

虽然代码里有 6 个特殊方法,但这些方法(除了 __init__)并不会在这个类自身的代码中使用。即便其他程序要使用这个类的这些方法,也不会直接调用它们,就像我们在上面的控制台对话中看到的。上文也提到过,一般只有 Python 的解释器会频繁地直接调用这些方法。接下来看看每个特殊方法的实现。

图灵地址 https://www.ituring.com.cn/book/1564

评论

发布