Python 中的神秘运算符

今天我们来讲讲 Python 里一个不为众人所知的运算符。你可能会觉得疑惑:还有我不知道的运算符?别急着下结论,先往下看看再说。

在 Python3.5 中通过 PEP465

(https://www.python.org/dev/peps/pep-0465)加入了 @运算符,也就是矩阵相乘运算符。虽然目前没有任何内置的 Python 类型实现了这个运算符的逻辑(就只是挖了个坑),但是如果你用过 numpy,大概对这个运算符的逻辑并不陌生:

>>> a = numpy.array([1, 2, 3])>>> b = numpy.array([10, 20, 30])>>> a @ b140>>> c = numpy.array([[10, 15], [20, 25], [30, 35]])>>> d = numpy.array([[4, 5, 6], [7, 8, 9]])>>> c @ darray([[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 @ yfor 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 神秘操作符。

注:本文来自编程教室的读者 @pynickle 即将发布的 GitChat 的一部分。

作者:pynickle

(0)

相关推荐

  • 概率计算:定义概率分布数据结构,Python实现概率分布计算

    使用Python实现马尔科夫随机场.蒙特卡洛采样等随机过程算法的前提,就是用Python实现概率的计算.并不只是数值计算,而是能够将随机模拟中常用的各种概率相关的操作,都能用计算机的数据结构来表达,其 ...

  • (2条消息) 一篇文章让你彻底搞懂神经网络:从原理到优化如此简单

    0. 文章介绍了什么 介绍了神经网络的基础单元--神经元neurons, 在神经元中使用了常见的激活函数: sigmoid  神经网络中的神经元是如何连接和交互的 创建了一个包含身高和体重(特征)作为 ...

  • 说说Python中的6种位运算符?

    公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助! 小猿会从最基础的面试题开始, ...

  • 生命中的神秘数字

    提  示 在卵子与精子结合,生命开始后,第一个七天,生成了督脉.上从间脑下达海底.第二个七天,生出左右两眼,此后则每七天一个变化,到了三十八个七天后,婴儿才会出世.   这也就是七日来复的道理,后天的 ...

  • 深入理解宇宙中最神秘的物体——黑洞,黑洞熵与热力学定律

    墨西哥裔.以色列裔美国理论物理学家贝肯斯坦是第一个提出黑洞存在的人--一个时空区域,引力非常强,连光都无法逃脱.他指出,黑洞应该有一个定义明确的熵.根据贝肯斯坦,我们可以这样定义黑洞熵: 黑洞熵是必须 ...

  • Python 中的函数装饰器和闭包

    函数装饰器可以被用于增强方法的某些行为,如果想自己实现装饰器,则必须了解闭包的概念. 装饰器的基本概念 装饰器是一个可调用对象,它的参数是另一个函数,称为被装饰函数.装饰器可以修改这个函数再将其返回, ...

  • Python中tuple和list的区别?基础学习!

    想必大家都知道,Python数据类型有很多种,其中有两个对象的写法非常相似,它就是tuple元组和list列表,让人傻傻分不清楚.那么你知道Python中tuple和list有什么区别吗?我们来看看具 ...

  • Python中缩进是什么?入门分享!

    众所周知,Python是一门独特的编程语言,它语法清晰.简单易学,而且Python是通过缩进来识别代码块的,因为一般的语言都是通过{}或者end来作为代码块标记. Python中缩进是什么? 要求严格 ...

  • 天文学家不断在天空中发现神秘圆环,它们究竟是什么?

    在过去的几年中,天文学家在遥远的宇宙中发现了一些巨大且几乎呈现完美圆形的无线电物体.尽管还没有人能解释这些神秘的物体,但是最近一个研究团队将另一个实体添加到了他们的目录中,有可能使他们更接近解决这一难 ...

  • python中的内置函数

    前言 本人只在csdn写博客 内置函数 介绍 一. 数学运算 abs()求绝对值函数 round() 近似取值 pow()求指数 divmod()求商和余数 max()求最大值和min()求最小值 s ...

  • 【Python核心编程笔记】一、Python中一切皆对象

    Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...