鱼C论坛

 找回密码
 立即注册
查看: 2577|回复: 17

43课课上内容求助

[复制链接]
发表于 2017-4-1 13:29:33 | 显示全部楼层 |阅读模式

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

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

x
  1. class Nint(int):
  2.         def __radd__(self , other):
  3.                 return int.__sub__(self , other)
复制代码

>>> a = Nint(5)
>>> b = Nint(3)
>>> a + b
8
>>> 1 + b
2
视频里说1 + b调用__radd__方法是因为1 没有 __add__方法,那请问1为什么没有__add__方法呢???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-4-1 13:41:24 | 显示全部楼层
1有__add__方法,但只是int和int相加的,没有int和Nint相加的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-1 16:48:06 | 显示全部楼层
冬雪雪冬 发表于 2017-4-1 13:41
1有__add__方法,但只是int和int相加的,没有int和Nint相加的。

原来如此 谢谢你 真是越学越难啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-1 16:49:56 | 显示全部楼层
冬雪雪冬 发表于 2017-4-1 13:41
1有__add__方法,但只是int和int相加的,没有int和Nint相加的。

所以说一定是要相同的一类 才可以使用__add__方法 对吗? 就比如:必须要 两个都是int , 或者两个都是Nint。一个是int 一个是Nint,就会调用__radd__?是这样理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-1 17:08:12 | 显示全部楼层
snakeshe 发表于 2017-4-1 16:49
所以说一定是要相同的一类 才可以使用__add__方法 对吗? 就比如:必须要 两个都是int , 或者两个都是Ni ...

不完全是,Nint + int则因为Nint继承了int的__add__,它能够处理Nint和int的相加,就不调用__radd__了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-1 20:16:39 | 显示全部楼层
冬雪雪冬 发表于 2017-4-1 17:08
不完全是,Nint + int则因为Nint继承了int的__add__,它能够处理Nint和int的相加,就不调用__radd__了。
  1. >>> class Nint(int):
  2.         def __radd__(self , other):
  3.                         return int.__sub__(self , other)

  4.                
  5. >>> a = Nint(5)
  6. >>> b = Nint(3)
  7. >>> c = 4
  8. >>> a + b
  9. 8
  10. >>> c + b
  11. -1
  12. >>> b + c
  13. 7
复制代码

所以 c + b = -1 是因为c是 int,虽然有__add__方法, 但是 b 是 Nint,所以就回调用 __radd___
而 b + c = 7 是因为 b是 Nint 它继承于 int 所以 它有 __ add__方法 ,而且 c 也是 int ,也有 __add__方法,所以可以产生正常的结果。是这样吗?
但是请问 c + b里面 Nint不是也是继承于 int 吗???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-1 20:24:56 | 显示全部楼层
如果能够左运算就不会右运算。
c + b先尝试c的__add__,但碰到b,做不下去,就反过来用b的__radd__,这回可以了,就返回-1
b + c先尝试b的__add__,Nint的b继承了int的方法other也是int,就可以做加法了,返回7

但是请问 c + b里面 Nint不是也是继承于 int 吗???
是的,但int没有继承Nint的方法,无法与Nint做加法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2021-8-7 11:35:12 | 显示全部楼层
冬雪雪冬 发表于 2017-4-1 20:24
如果能够左运算就不会右运算。
c + b先尝试c的__add__,但碰到b,做不下去,就反过来用b的__radd__,这回 ...

class Nint(int):
        def __radd__(self , other):
                return int.__sub__(self , other)

class C(int):
        pass

b = Nint(3)
c = C(4)

运行结果:

>>> c+b
7

疑问:c也没有继承Nint的方法,但可以直接与Nint做加法   (·_·?)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-7 15:19:19 | 显示全部楼层
bravsheng 发表于 2021-8-7 11:35
class Nint(int):
        def __radd__(self , other):
                return int.__sub__(self , o ...

c没有和b相加的方法,b有和int右加的方法。我认为c是继承int的,所以右加的的方法也适用于b,不知这样的理解对不对
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2021-8-7 15:30:23 | 显示全部楼层
冬雪雪冬 发表于 2021-8-7 15:19
c没有和b相加的方法,b有和int右加的方法。我认为c是继承int的,所以右加的的方法也适用于b,不知这样的 ...

可是查看到c也有add的方法呀
>>> dir(c)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dict__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-7 15:41:23 | 显示全部楼层
冬雪雪冬 发表于 2021-8-7 15:19
c没有和b相加的方法,b有和int右加的方法。我认为c是继承int的,所以右加的的方法也适用于b,不知这样的 ...


class B(int):
    def __add__(self , other):
        print("调用b的__add__")
        return int.__add__(self , other)

    def __radd__(self , other):  
        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
>>> type(a)
<class '__main__.A'>
>>> type(b)
<class '__main__.B'>
>>> type(4)
<class 'int'>
>>>

我的疑惑: (·_·?)  
4+b:4和b分别来源与int类和B类,因为类型不同,调用a的add方法没成功,转而调用b的radd的方法。
a+b:a和b分别来源于A,B两个类,但a的add方法可以成功运行!
a,b算同一类型嘛?  怎么解释可以更好的理解? >_<
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-8 12:38:37 | 显示全部楼层
bravsheng 发表于 2021-8-7 15:30
可是查看到c也有add的方法呀
>>> dir(c)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', ...

c是继承int,所以有int和int相加的__add__,但没有和Nint相加的__add__
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-8 12:46:30 | 显示全部楼层
bravsheng 发表于 2021-8-7 15:41
class B(int):
    def __add__(self , other):
        print("调用b的__add__")

4 + b,你理解的正确
a + b,我也不清楚内在的逻辑,从继承关系看,两者都继承于int,可以认为加后右面为其父类或也是继承其父类是可以__add__运算的
  1. >>> A.mro()
  2. [<class '__main__.A'>, <class 'int'>, <class 'object'>]
  3. >>> B.mro()
  4. [<class '__main__.B'>, <class 'int'>, <class 'object'>]
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2021-8-8 13:35:46 | 显示全部楼层
冬雪雪冬 发表于 2021-8-8 12:46
4 + b,你理解的正确
a + b,我也不清楚内在的逻辑,从继承关系看,两者都继承于int,可以认为加后右面 ...

它的逻辑应该是:
因为有继承关系(即使不继承int,也会默认继承object总父类),
所以 + 运算符,先触发 .__add__(), 本类里没有就会按 .mro()的"基类顺序"找方法__add__,找到就用。
找不到,就尝试 找 __radd__() 。

注:这是大概逻辑,具体还涉及运算结果是否为NotImplenment的判断...

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

使用道具 举报

发表于 2021-8-8 13:46:37 | 显示全部楼层
阿奇_o 发表于 2021-8-8 13:35
它的逻辑应该是:
因为有继承关系(即使不继承int,也会默认继承object总父类),
所以 + 运算符,先触 ...

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

使用道具 举报

发表于 2021-8-8 14:48:50 | 显示全部楼层
冬雪雪冬 发表于 2021-8-8 12:46
4 + b,你理解的正确
a + b,我也不清楚内在的逻辑,从继承关系看,两者都继承于int,可以认为加后右面 ...

谢谢,有点明白了!  mro可以能看到继承顺序呀。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-8 14:50:49 | 显示全部楼层
冬雪雪冬 发表于 2021-8-8 12:38
c是继承int,所以有int和int相加的__add__,但没有和Nint相加的__add__

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

使用道具 举报

发表于 2021-8-8 14:57:35 | 显示全部楼层
阿奇_o 发表于 2021-8-8 13:35
它的逻辑应该是:
因为有继承关系(即使不继承int,也会默认继承object总父类),
所以 + 运算符,先触 ...

谢谢解答!
所以a是往上找到了<class 'int'>的__add__方法吗?   b需要往上找到int类型吗?
可以讲下a+b的实现过程嘛?   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 02:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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