教育改变生活
标题: Python 中的神秘运算符 [打印本页]
作者: 李玮    时间: 2020-10-23 17:58
标题: Python 中的神秘运算符
今天我们来讲讲 Python 里一个不为众人所知的运算符。你可能会觉得疑惑:还有我不知道的运算符?别急着下结论,先往下看看再说。
- >>> a = numpy.array([1, 2, 3])
 - >>> b = numpy.array([10, 20, 30])
 - >>> a @ b
 - 140
 - >>> c = numpy.array([[10, 15], [20, 25], [30, 35]])
 - >>> d = numpy.array([[4, 5, 6], [7, 8, 9]])
 - >>> c @ d
 - array([[145, 170, 195],
 -        [255, 300, 345],
 -        [365, 430, 495]])
 
 复制代码
如今,在原生的 Python 代码中,你也可以使用这个运算符。但前提是,你得自己实现具体的运算规则,也就是实现 __matmul__(),__rmatmul__() 和 __imatmul__() 这3个方法。
在看实例之前,我们先来了解下这种特殊的类方法。
在官方文档中,我们看到与 __matmul__ 方法一起介绍的还有 __add__,__sub__ 等等(注意前后都是2个下划线),这些方法都是用来定义此类型的运算符号。
假设现在有一个类叫 A,我们在其 class 中实现了加法方法 __add__:
- def __add__(self, value):
 -     # 具体实现代码(略)
 
 复制代码
那么我们就可以在代码中对 A 的实例进行加法运算:
- a = A()
 - b = A()
 - c = a + b
 
 复制代码此种情况下,__add__ 函数会被调用,self 对应的是 a 变量,而 value 对应的则是 b 变量。
__matmul__ 与之类似,唯一的不同就是它会在使用 @ 操作符而不是 + 时被调用。
同样的道理,__rmatmul__ 对应操作数不支持相关运算或者类型不同的情况,__imatmul__ 则对应复合赋值运算符的情况:
- a = A()
 - b = A()
 - c = a @ b  # __matmul__
 - d = a @ 1  # __rmatmul__
 - a @= 1  #__imatmul__
 
 复制代码
接下来我们来创建一个继承 list 的类并实现矩阵乘法:
- class NewList(list):
 -     def __matmul__(self, v):
 -         result = []
 -         for i in range(len(self)):
 -             result.append([])
 -             for j in range(len(v[0])):
 -                 result[i].append(0)
 
-         for i in range(len(self)):
 -             for j in range(len(v[0])):
 -                 for k in range(len(v)):
 -                     result[i][j] += self[i][k] * v[k][j]
 -         return result
 
- # 测试
 - x = NewList([[7, 7, 3],
 -     [4, 5, 6],
 -     [6, 4, 3]])
 
- y = NewList([[5, 4, 1, 2],
 -     [6, 2, 3, 0],
 -     [4, 5, 6, 1]])
 
- z = x @ y
 - for i in z:
 -     print(i)
 
 复制代码
输出结果:
- [89, 57, 46, 17]
 - [74, 56, 55, 14]
 - [66, 47, 36, 15]
 
 复制代码
虽然这个符号的设定是用于矩阵乘法,但实际上可以自定义为任何操作。比如我们可以用它来计算直角坐标系上两个点之间的距离:
- from math import sqrt
 
- class Point:
 -     def __init__(self, x, y):
 -         self.x = x   # x坐标
 -         self.y = y   # y坐标
 
-     def __matmul__(self, value):
 -         x_sub = self.x - value.x
 -         y_sub = self.y - value.y
 -         return sqrt(x_sub**2 + y_sub**2)
 
- a = Point(1, 3)
 - b = Point(4, 7)
 - print(a @ b)
 
 复制代码
以上便是我今天跟大家分享的 Python 神秘操作符。
| 欢迎光临 教育改变生活 (http://bbs.goldoar.com/) | 
Powered by Discuz! X3.2 |