Python:rtruediv无法正常工作

时间:2016-05-18 21:03:57

标签: python operator-overloading division

使用python的V3,我创建:

class NewInt(int):
  def __rtruediv__(self, num):
    print('in here')

x = NewInt(5)

343 / x    # called rtruediv as I expect, but

343.3 / x  # does not call rtruediv

不确定为什么这是因为:

x / 343
x / 343.3   #both will call truediv

对我而言,这似乎不一致..

任何人都有解释为什么这是..当Python确实343.3 / x有一个可以覆盖的方法?

我在查看有关过载的一些信息时发现了这种行为,并发现了这种不一致。

戴夫

2 个答案:

答案 0 :(得分:3)

如果右侧操作数是左侧操作数类的子类的实例,则

343 / x仅优先于NewInt

执行int后,__rtruediv__343.3 / x的子类,因此x​​ NewInt获得优先权。执行float时,__truediv__不是343.3.__truediv__(x)的子类,因此343.3 NotImplemented获得优先权。

float不返回x.__rtruediv__,因为{{1}}知道如何用浮点数划分浮点数。因此,{{1}}不会被调用。

答案 1 :(得分:3)

简而言之,左操作数是处理操作的第一个镜头,除非在某些特殊情况下。

此处的相关文档位于emulating numeric types

  

注意:如果右操作数的类型是左操作数类型的子类,并且该子类提供了操作的反射方法,则此方法将在左操作数的非反射方法之前调用。此行为允许子类覆盖其祖先的操作。

所以在:

的情况下
343.3 / x  # does not call rtruediv

左手获胜是因为float除以intNewInt is a n int。也就是说,343.3.__truediv__(x)成功而没有错误。

让我们根据文档协调所有四个案例,看看这里没有任何不一致的行为:

343 / x     # x.__rtruediv__ wins because NewInt subclasses int
343.3 / x   # 343.3.__truediv__ wins because NewInt doesn't subclass float
x / 343     # x.__truediv__ wins because int doesn't subclass NewInt
x / 343.3   # x.__truediv__ wins because float doesn't subclass NewInt