鱼C论坛

 找回密码
 立即注册
查看: 50|回复: 2

[已解决]魔法方法问题求助

[复制链接]
发表于 7 天前 | 显示全部楼层 |阅读模式

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

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

x
  • >>> class S(str):
  • ...     def __radd__(self, other):
  • ...         return len(self) + len(other)
  • ...
  • >>> s = S("FishC")
  • >>> "Apple" + s
  • # 请问这里会打印什么内容?10
  • 有鱼油可能会有疑惑,就是普通字符串("Apple")自身不是有 __add__(),为什么还会调用 s__radd__() 呢?
    因为这里能够成功调用到 __radd__() 方法,首先当然是因为 S 实现了 __radd__() 方法;其次,两个操作数是两个基于不同类的对象;
    再有一个条件,就是第一个操作数必须不能实现 __add__() 方法,不然还是会优先去执行左侧对象的 __add__() 方法(这里说的是自定义 __add__() 方法,而默认内置的 __add__() 是不算的。
还是没搞懂这题,普通字符串("Apple")自身有 __add__(),为什么还会调用 s__radd__() 呢?__radd__() 的定义说当左操作数不支持相应操作(__add__())时,才会去调用__radd__() 吗?
最佳答案
7 天前
普通字符串(如"Apple")确实有内置的 `__add__()` 方法,但是在某些情况下也会调用右操作数的 `__radd__()`。这主要是由于 Python 对处理不同类型对象的加法操作时的行为定义。

在你的例子中:
>>> class S(str):
...     def __radd__(self, other):
...         return len(self) + len(other)
...
>>> s = S("FishC")
>>> "Apple" + s

之所以调用 `s` 的 `__radd__()` 方法,是因为 Python 的内置字符串对象 `"Apple"` 和自定义的 `S` 类型对象 `s` 之间的操作没有直接的方式进行,Python 会尝试使用右操作数的 `__radd__()` 方法来完成操作。

当左侧对象是内置类型的情况下,即使它有 `__add__()`,Python 的运算规则也允许调用 `S` 类型右操作数的 `__radd__()` 方法来尝试进行加法运算。这是因为 Python 在处理不同类型的对象混合运算时,会尝试为每种可能执行的操作寻找最合适的实现。

综上所述,虽然 `"Apple"` 有 `__add__()` 方法,但是在这种跨类型计算时,Python 会优先检查自定义对象(如 `S`)是否有定义 `__radd__()`,以求达成兼容性运算。

所以,`"Apple" + s` 会调用 `s` 的 `__radd__()`,并返回 `10`,因为字符串 `"Apple"` 和 `"FishC"` 的总长度为 `10`。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 7 天前 | 显示全部楼层    本楼为最佳答案   
普通字符串(如"Apple")确实有内置的 `__add__()` 方法,但是在某些情况下也会调用右操作数的 `__radd__()`。这主要是由于 Python 对处理不同类型对象的加法操作时的行为定义。

在你的例子中:
>>> class S(str):
...     def __radd__(self, other):
...         return len(self) + len(other)
...
>>> s = S("FishC")
>>> "Apple" + s

之所以调用 `s` 的 `__radd__()` 方法,是因为 Python 的内置字符串对象 `"Apple"` 和自定义的 `S` 类型对象 `s` 之间的操作没有直接的方式进行,Python 会尝试使用右操作数的 `__radd__()` 方法来完成操作。

当左侧对象是内置类型的情况下,即使它有 `__add__()`,Python 的运算规则也允许调用 `S` 类型右操作数的 `__radd__()` 方法来尝试进行加法运算。这是因为 Python 在处理不同类型的对象混合运算时,会尝试为每种可能执行的操作寻找最合适的实现。

综上所述,虽然 `"Apple"` 有 `__add__()` 方法,但是在这种跨类型计算时,Python 会优先检查自定义对象(如 `S`)是否有定义 `__radd__()`,以求达成兼容性运算。

所以,`"Apple" + s` 会调用 `s` 的 `__radd__()`,并返回 `10`,因为字符串 `"Apple"` 和 `"FishC"` 的总长度为 `10`。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 7 天前 | 显示全部楼层
你带上对象就知道了,因为普通字符串的 __add__ 是 str.__add__,而不是 S.__add__,所以字符串是没有实现 S.__add__的,当 str + S 的时候就会去调用 S.__radd__
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-2 21:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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