鱼C论坛

 找回密码
 立即注册
查看: 4682|回复: 8

[已解决]二问:Py 第43课,算数2,反运算

[复制链接]
发表于 2021-3-15 10:13:32 | 显示全部楼层 |阅读模式
10鱼币
本帖最后由 Peteryo01223 于 2021-3-15 10:34 编辑

Fish C,在‘第43课,算数2’的视频中,第5至6分钟,Fish C 举的反运算例子
  1. class Nint(int):
  2.         def __radd__(self, other):
  3.                 return int.__sub__(self, other)
复制代码

run后结果:
  1. >>> a = Nint(5)
  2. >>> b = Nint(3)
  3. >>> a + b # 没有触发反运算 __radd__ 方法
  4. 8
  5. >>> 1 + b # 触发了反运算 __radd__ 方法。这里 self 是变量 b, other 是常数 1
  6. 2
复制代码

Fish C 解释说:
因为
  • Python 找得到 a,也找得到 b,所以 a+b 不能触发 __radd__方法,故此 Python 按原本的 __add__ 方法运算,得出 8。
  • 反之,
因 Python 在 1+b 中找不到 a,所以就触发了反运算 __radd__方法,得到了结果 2。

提问:
Python 哪里规定过:找不到 a 就触发反运算,反之不触发?费解。我猜想,是不是因为:class 中定义过 self 和 other 两个变量,所以只要运算时出现了两个变量,即不能“触发”?但是,这逻辑,貌似也不通。求教!
最佳答案
2021-3-15 10:13:33
本帖最后由 jackz007 于 2021-3-15 23:51 编辑

radd.png
  
        图片来自 Python 3.8.7 手册

If the right operand’s type is a subclass of the left operand’s type and that subclass provides a different implementation of the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.

        百度翻译译文如下:
        如果右操作数的类型是左操作数类型的子类,并且该子类为操作提供了反射方法的不同实现,则将在左操作数的非反射方法之前调用此方法。这种行为允许子类覆盖其祖先的操作。

        显然,这是 Python 对象的规则策略。

最佳答案

查看完整内容

图片来自 Python 3.8.7 手册 If the right operand’s type is a subclass of the left operand’s type and that subclass provides a different implementation of the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations. 百度翻译译文如下: ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-3-15 10:13:33 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2021-3-15 23:51 编辑

radd.png
  
        图片来自 Python 3.8.7 手册

If the right operand’s type is a subclass of the left operand’s type and that subclass provides a different implementation of the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.

        百度翻译译文如下:
        如果右操作数的类型是左操作数类型的子类,并且该子类为操作提供了反射方法的不同实现,则将在左操作数的非反射方法之前调用此方法。这种行为允许子类覆盖其祖先的操作。

        显然,这是 Python 对象的规则策略。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-3-15 10:57:01 | 显示全部楼层
我觉得是因为第一个数不支持加运算,所以使用了第二个数的反运算
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-3-15 11:00:29 | 显示全部楼层
  1. >>> class Nint(int):
  2.         def __radd__(self, other):
  3.                 return int.__sub__(self, other)

  4. >>> a = Nint(4)
  5. >>> type(a)
  6. <class '__main__.Nint'>
  7. >>> type(1)
  8. <class 'int'>
  9. >>> 1 + a
  10. 3
复制代码
个人理解就是他们类型不一样,不支持加的操作,所以用了第二个数的反运算
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-3-15 13:35:43 | 显示全部楼层
柿子饼同学 发表于 2021-3-15 11:00
个人理解就是他们类型不一样,不支持加的操作,所以用了第二个数的反运算

好的,我再等等其他答案哈,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-3-15 18:57:29 | 显示全部楼层
个人理解 :1 是类型 int ;而 b 是 类型 Nint。不同类型之间是不支持算数运算的。1 + b 中,先调用1 的__add__方法,发现1 和 b 不是同一类型,所以无法实现 + 操作,从而使用 b的  __radd__ 方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-3-16 10:02:16 | 显示全部楼层
弈秋呜呜呜 发表于 2021-3-15 18:57
个人理解 :1 是类型 int ;而 b 是 类型 Nint。不同类型之间是不支持算数运算的。1 + b 中,先调用1 的__ad ...

感谢指点~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-3-16 10:03:00 | 显示全部楼层
jackz007 发表于 2021-3-15 10:13
图片来自 Python 3.8.7 手册

If the right operand’s type is a subclass of the left o ...

这个英文解释准确,谢谢大佬!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-6 17:57:05 | 显示全部楼层
弈秋呜呜呜 发表于 2021-3-15 18:57
个人理解 :1 是类型 int ;而 b 是 类型 Nint。不同类型之间是不支持算数运算的。1 + b 中,先调用1 的__ad ...

学习了,我觉得你的这个解释更容易理解些!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-20 20:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表