网易首页 > 网易号 > 正文 申请入驻

Python:数值运算协议

0
分享至

数值运算协议(Numeric Operation Protocol)是 Python 在处理算术表达式时所遵循的一套核心规则。它规定了解释器在遇到 a + b、a * b、a ** b、-a、a += b 等语法结构时,应当如何判定参与对象是否可以建立运算语义,以及在判定成立后,沿何种严格顺序展开执行路径。

理解数值运算协议,关键不在于记住若干特殊方法名,而在于把握一个更根本的逻辑:

算术运算并不是对象主动执行的能力,而是解释器在算术语法语境下所采用的一套解释规则。

对象是否“支持加法”或“支持乘法”,并非其固有属性,而是解释器在特定语法结构中,对其类型结构应用数值运算协议后的判定结果。

一、什么是数值运算协议

在 Python 中,数值运算符有:

二元运算:+ - * / // % ** @ << >> & ^ |

一元运算:-x +x ~x abs(x)

就地运算:+= -= *= /= ...

当解释器遇到如下语法:

a + b

它首先识别这是一次加法语法结构,然后触发数值运算协议解释路径。

数值运算协议是一套统一规则,但在不同运算符参与时,会沿不同的语义分支展开。尽管 + 与 * 语义不同,它们共享同一分派模型。

数值运算协议并不是运行期实体,也不是某种接口类型。它存在于解释器的规则体系之中。

二、数值运算协议的方法构成

数值运算协议涉及以下几类核心方法。

1、二元运算方法(左侧路径)

__or__(self, other)         # |

2、反向二元运算方法(右侧兜底路径)

__ror__(self, other)         # |

3、就地运算方法(优先路径)

__ior__(self, other)         # |=

4、一元运算方法

__invert__(self)   # ~x

这些方法本身只是定义在类中的普通函数对象。它们不会因为名称特殊而自动生效。

数值运算协议不通过实例属性查找流程(即不会触发 __getattribute__ 或 __getattr__)。解释器在运算语境下直接从类型对象的数值槽位结构(PyNumberMethods)读取对应入口。

三、自定义数值运算(以加法为例)

数值运算协议允许用户通过定义特殊方法参与算术语义的建立。以下以加法运算为例说明。

print(v3.x)   # 7

自定义运算并不是“给对象添加一个能力”,而是在特定运算语境(如 v1+ v2)中,为解释器提供一个可被选中的协议入口。

四、实例属性不会影响数值运算协议

与调用协议、比较协议一致,数值运算协议的判定发生在类型层面,而不是实例字典。

例如:

a + b      # TypeError

尽管实例 a 拥有名为 __add__ 的属性,但解释器在加法语境中不会通过普通属性访问机制进行判定,而是读取类型层的数值运算入口。

因此,运算能力并不来自实例属性,而来自类型结构中的协议实现。

五、二元运算的严格顺序(以加法为例)

对于表达式:

a + b

其解释路径(严格顺序)为:

1、解释器首先检查 type(b) 是否是 type(a) 的真子类:

issubclass(type(b), type(a)) and type(a) != type(b)

→ 若是, 按子类优先原则, 读取 type(b) 的数值运算槽位, 优先尝试右侧反向路径:

   type(b).__radd__(b, a)

→ 若不是,则按以下的左侧正向路径展开。

2、读取 type(a) 的数值运算槽位(在 CPython 中为 PyNumberMethods.nb_add),调用。

   type(a).__add__(a, b)

3、若正向路径返回 NotImplemented,则尝试反向路径:

   type(b).__radd__(b, a)

4、若所有路径均返回 NotImplemented,抛出 TypeError。

(1)解释器首先把运算视为“左操作数主导的运算尝试”,因此第一候选路径以左操作数的数值槽位作为入口,常称为“正向路径”或“主导路径”。

(2)还有一条候选路径是以右操作数的数值槽位作为入口,称为“反向路径”或“协议兜底路径”。

(3)先尝试正向路径,若失败再尝试反向路径,这是数值运算协议的最核心的分派模型。

(4)返回 NotImplemented 表示“该类型无法处理该组合”,从而允许解释器继续尝试其他候选路径。

(5)数值运算协议支持子类优先规则。当右操作数类型是左操作数类型的真子类时,解释器优先调用右侧类型的反向方法,以保证子类可以覆盖父类运算语义。

因此,a + b 并不是简单调用某个方法,而是在加法语境中触发一次受规则控制的协议分派。

其他二元运算(- * / // % ** @ << >> & ^ |)均遵循同样结构,只是对应不同槽位与方法名。

协议分派发生在类型层数值槽位结构中,而不是通过常规属性访问流程,因此它不是通过实例属性查找机制触发的方法调用,而是由解释器在运算语境中直接读取类型槽位并完成的协议分派。

六、一元运算的解释路径

对于表达式:

-a

解释路径为:

1、读取 type(a) 的对应一元运算槽位(如 nb_negative);

2、调用:

type(a).__neg__(a)

3、若不存在该入口,抛出 TypeError。

一元运算不涉及反向协商,因此不存在双向路径。

七、就地运算的优先分支

表达式:

a += b

其解释路径为:

1、读取 type(a) 的就地运算槽位(在 CPython 中表现为 nb_inplace_add),调用:

type(a).__iadd__(a, b)

2、若不存在该入口或返回 NotImplemented,则回退为普通二元运算路径(见前面章节)。

3、最终将结果重新绑定到变量名。

需要强调的是:

• “就地”并不保证原地修改对象

• 是否原地修改完全由类型实现决定

• 协议仅规定分派顺序。

八、位运算与矩阵运算

位运算(& ^ | << >>)与矩阵乘法(@)在协议结构上完全遵循与加法相同的分派模型:

• 读取对应数值槽位

• 先尝试正向路径,若失败再尝试反向路径

• 子类优先插队规则

• NotImplemented 协商

• 失败抛出 TypeError

它们不是独立机制,而是数值运算协议的不同分支。

九、数值运算协议的典型应用场景

数值运算协议贯穿 Python 语言的多个核心机制:

1、算术表达式计算

2、数值类型模拟(自定义向量、矩阵等)

3、就地修改语义

4、位运算与底层数据结构操作

5、框架中重载运算符的 DSL 设计

这些场景的共同点在于:对象并未“执行运算”,而是在算术语法语境下,被解释器按协议规则解释为参与运算的操作数。

小结

数值运算协议不是对象模型中的实体,而是一组由解释器遵循的运算分派规则。它规定了解释器在运算语法语境中如何判定对象是否可参与运算、如何在类型结构中寻找语义入口,以及在协商失败时如何处理。对象是否“支持某种运算”,并不取决于名称或类别标签,而取决于解释器在特定语境下对其类型结构应用数值运算协议后的结果。


点赞有美意,赞赏是鼓励

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
她是钢琴公主,是王宏伟的妻子,与婆婆生活18年,只拌过两次嘴

她是钢琴公主,是王宏伟的妻子,与婆婆生活18年,只拌过两次嘴

让心灵得以栖息
2026-02-19 22:01:23
蒯曼春节回老家晒照,意外曝光真实家境!“富家女”谣言不攻自破

蒯曼春节回老家晒照,意外曝光真实家境!“富家女”谣言不攻自破

陌识
2026-02-19 11:59:33
天山胜利隧道通车即堵车,新疆车主集体避走隧道,宁愿绕甘沟

天山胜利隧道通车即堵车,新疆车主集体避走隧道,宁愿绕甘沟

旭芯怡
2026-02-19 14:17:41
滑疯了!宁忠岩破纪录之夜,打破美国选手3金梦,中国队飙升2名

滑疯了!宁忠岩破纪录之夜,打破美国选手3金梦,中国队飙升2名

何老师呀
2026-02-20 02:38:43
俄军钳形猛攻波克罗夫斯克,却被乌军连破21次!

俄军钳形猛攻波克罗夫斯克,却被乌军连破21次!

知兵
2026-02-19 21:39:29
美军宣布:发动空袭

美军宣布:发动空袭

中国基金报
2026-02-15 16:10:23
切尔西昔日巨星彻底拉胯!球迷怒喷:上他等于少打一人

切尔西昔日巨星彻底拉胯!球迷怒喷:上他等于少打一人

澜归序
2026-02-20 04:10:16
警报!三种“毒早餐”竟成家长的心头好,快来看看你在喂什么!

警报!三种“毒早餐”竟成家长的心头好,快来看看你在喂什么!

特约前排观众
2026-01-25 00:20:06
詹姆斯湖人夺冠梦真完了,艾顿被抓,或面临10年牢狱之灾

詹姆斯湖人夺冠梦真完了,艾顿被抓,或面临10年牢狱之灾

生活新鲜市
2026-02-19 01:00:55
科学家让一对情侣在核磁共振里实战,才发现人体惊人真相!

科学家让一对情侣在核磁共振里实战,才发现人体惊人真相!

徐德文科学频道
2026-01-06 19:51:55
心脏最怕的4件事,你可能每天都在做!快停下

心脏最怕的4件事,你可能每天都在做!快停下

大象新闻
2026-02-19 07:52:05
60万人逃离 1.3万人逆行:中国赴日游客锐减下的坚持与博弈

60万人逃离 1.3万人逆行:中国赴日游客锐减下的坚持与博弈

东极妙严
2026-02-19 19:01:02
2023年,985女硕士王懿在东京活活饿死,父母拒绝为其收尸

2023年,985女硕士王懿在东京活活饿死,父母拒绝为其收尸

谈史论天地
2026-02-18 17:45:40
暴雪,新一轮强冷空气:降温16度,大范围雨雪21日来,台风有吗?

暴雪,新一轮强冷空气:降温16度,大范围雨雪21日来,台风有吗?

环球科学猫
2026-02-19 19:57:23
不要再为贺红梅感到惋惜了,55岁升任高官的她,早已今非昔比

不要再为贺红梅感到惋惜了,55岁升任高官的她,早已今非昔比

巧手晓厨娘
2026-01-16 15:41:54
神二十三就位!杨利伟:为登月锻炼,3名“老”航天员还会飞天吗

神二十三就位!杨利伟:为登月锻炼,3名“老”航天员还会飞天吗

Thurman在昆明
2026-02-20 01:21:07
白粥小花靠大佬撕晚会资源?李一桐陈星旭互掐?张婧仪外网被骂?邓为被限制?姨太问答

白粥小花靠大佬撕晚会资源?李一桐陈星旭互掐?张婧仪外网被骂?邓为被限制?姨太问答

毒舌扒姨太
2026-02-19 22:12:53
陈道明曾告诫女儿:宁可嫁个没文化的,也别碰这种“精致流氓”。

陈道明曾告诫女儿:宁可嫁个没文化的,也别碰这种“精致流氓”。

阿废冷眼观察所
2026-02-07 19:59:27
杨澜爆料撕下王菲伪装,揭秘谢霆锋拒绝结婚真相

杨澜爆料撕下王菲伪装,揭秘谢霆锋拒绝结婚真相

潘殤旅行浪子
2026-01-03 22:14:17
女孩从陕西嫁到重庆,过年本来准备带宝宝回老家看父母,结果母亲让她不要回去了。

女孩从陕西嫁到重庆,过年本来准备带宝宝回老家看父母,结果母亲让她不要回去了。

张晓磊
2026-02-15 11:11:05
2026-02-20 05:43:00
MediaTea
MediaTea
专业的数字媒体、新媒体技术
1760文章数 76关注度
往期回顾 全部

科技要闻

怒烧45亿,腾讯字节阿里决战春节

头条要闻

美专家:美国若武力介入台湾 或致美数十万人死亡

头条要闻

美专家:美国若武力介入台湾 或致美数十万人死亡

体育要闻

不想退役!徐梦桃:希望能参加第6次冬奥

娱乐要闻

霍启山恋情再添实锤 和娜然同游意大利

财经要闻

面条火腿香菇酱!上市公司这些年请你吃

汽车要闻

量产甲醇插混 吉利银河星耀6甲醇插混版申报图

态度原创

游戏
教育
数码
家居
公开课

新《古墓丽影》游戏或将翻车!前制作人爆猛料

教育要闻

“我的硕士白读了!”上外女硕士签约国有银行,跟干服务员没区别

数码要闻

REDMI耳机新品曝光,满电37小时续航

家居要闻

本真栖居 爱暖伴流年

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版