鱼C论坛

 找回密码
 立即注册
查看: 1686|回复: 11

鱼油们,帮忙看下 b+4 怎么解释?【来自第43课《魔法方法:算术运算2 》的一个问题】

[复制链接]
发表于 2021-8-6 18:41:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 bravsheng 于 2021-8-7 08:56 编辑

鱼油们,帮忙解释下:为什么b+4是可以正常进行加法?

4 + b :先调用4 的__add__方法,发现4 和 b 不是同一类型,无法实现 + 操作,转而使用 b的  __radd__ 方法。  
(根据官方解释:右类型是左类型的子类,并且右类型有反方法,那就先执行右类型的反方法)
b + 4  : 怎么解释呢?  b和4也不是同一类型,是直接进行了b的add方法,还是调用了4的 r_add反方法?

我没想明白,鱼油们帮忙解释下。
代码如下:
class Nint(int):
    def __radd__(self , other):
        return int.__sub__(self , other)

>>> a = Nint(5)
>>> b = Nint(3)
>>> 4 + b
-1
>>> b + 4
7
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-6 19:28:41 | 显示全部楼层
b+4也不是同一个逻辑吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-6 19:31:49 | 显示全部楼层
你的意思是 4 + b 调用了 b的  __radd__ ,然后变成b + 4,然后又调用4的  __radd__  .... 一直循环吗?

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2021-8-6 21:01:12 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-8-6 21:07 编辑


我错了。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-7 08:52:31 | 显示全部楼层
大马强 发表于 2021-8-6 19:31
你的意思是 4 + b 调用了 b的  __radd__ ,然后变成b + 4,然后又调用4的  __radd__  .... 一直循环吗?

对对,我是这么想的。  这两个不是同类型,会不会一直循环...

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

使用道具 举报

 楼主| 发表于 2021-8-7 09:03:32 | 显示全部楼层
大马强 发表于 2021-8-6 19:31
你的意思是 4 + b 调用了 b的  __radd__ ,然后变成b + 4,然后又调用4的  __radd__  .... 一直循环吗?

厉害呀,我当时发帖忘记附上代码了,你居然也理解了我的意思。
我把代码贴上了,你再帮我看一下这个情形。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-7 09:07:42 | 显示全部楼层
bravsheng 发表于 2021-8-7 09:03
厉害呀,我当时发帖忘记附上代码了,你居然也理解了我的意思。
我把代码贴上了,你再帮我看一下这个情形 ...

你看我发的那张截图,证明是不会的,4+b,就只触发了b的radd,
我猜可能原radd方法可能有触发报错提示的函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-7 09:18:58 | 显示全部楼层
大马强 发表于 2021-8-7 09:07
你看我发的那张截图,证明是不会的,4+b,就只触发了b的radd,
我猜可能原radd方法可能有触发报错提示的函 ...

噢,4+b我已经明白了。 我试了下你截图的代码,b+4好像是直接触发了b的add方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-7 09:32:48 | 显示全部楼层
bravsheng 发表于 2021-8-7 09:18
噢,4+b我已经明白了。 我试了下你截图的代码,b+4好像是直接触发了b的add方法。

可能str的__add__方法和整型不一样,因为str相加是拼接
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-8-7 10:05:29 | 显示全部楼层
本帖最后由 bravsheng 于 2021-8-7 10:07 编辑
大马强 发表于 2021-8-6 19:31
你的意思是 4 + b 调用了 b的  __radd__ ,然后变成b + 4,然后又调用4的  __radd__  .... 一直循环吗?


你截图的方法真的好用,能看出是哪个对象被调用了它的哪种方法!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-7 10:14:41 | 显示全部楼层
bravsheng 发表于 2021-8-7 10:05
你截图的方法真的好用,能看出是哪个对象被调用了它的哪种方法!

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

使用道具 举报

 楼主| 发表于 2021-8-7 10:16:18 | 显示全部楼层
本帖最后由 bravsheng 于 2021-8-7 10:30 编辑

class B(int):
    def __add__(self , other):
        print("调用b的__add__")
        return int.__add__(self , other)
    def __radd__(self , other): #把B的radd改写成减法
        print("调用b的__radd__")
        return int.__sub__(self , other)

class A(int):
    def __add__(self , other):
        print("调用a的__add__")
        return int.__add__(self , other)        
   
a = A(4)
b = B(3)
执行结果:
>>> 4+b
调用b的__radd__
-1
>>> a+b
调用a的__add__
7

这里我还是有点疑问: (·_·?)
4和b分别来源与int类和B类,调用a的add方法没成功,转而去找b的radd的方法。
a和b分别来源于A,B两个类, 这算是同一类型吗? 为什么a的add方法可以成功运行!?  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-13 20:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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