Python 运算法重载之右侧加法

网友投稿 327 2022-09-08


Python 运算法重载之右侧加法

右侧加法

让我们有一个类名示例,它由一个函数 ​​__add__​​ 组成,该函数接受一个参数并将该参数与类中可用的数据连接起来。首先,Python 查看 x 和 y 的类型来决定是调用 ​​x.__add__​​ 还是 ​​y.__radd__​​。由于它们都是相同类型的 Commuter,它首先尝试 ​​x.__add__​​。

class Computer: def __init__(self, val): self.val = val def __add__(self, other): print("add", self.val, other) return self.val + otherfirst = Computer(1)second = Computer(2)print(first + 1)print(second + 1)

运行结果:

('add', 1, 1)2('add', 2, 1)3

但如果我们这样使用:

class Computer: def __init__(self, val): self.val = val def __add__(self, other): print("add", self.val, other) return self.val + other# first = Computer(1)second = Computer(2)# print(first + 1)# print(second + 1)print(1 + second)

会得到如下的错误。​​TypeError: unsupported operand type(s) for +: 'int' and 'instance'​​

如果我们传入字符串呢?

class sample: def __init__(self, value): self.data = value def __add__(self, other): return self.data + otherOb1 = sample("test")Ob2 = sample("Operator")Ob3 = Ob1 + Ob2print(Ob3)

我们运行上面的代码会得到这样的错误:​​TypeError: cannot concatenate 'str' and 'instance' objects​​。

原因是:Python 会根据 ​​self.val​​ 和 ​​other​​ 的类型来决定是调用 ​​self.val.__add__​​ 还是 ​​other.__radd__​​。由于它们是不相关的类型 int 和 Commuter,它首先尝试 ​​int.__add__​​。

但是 ​​int.__add__​​ 为不知道的类型返回 NotImplemented,因此 Python 回退到调用 ​​other.__radd__​​

所以为了解决这个问题,我们使用 ​​__radd__​​ 函数,它也会添加 this 并返回 other.a + self.a。只有当 + 右侧是实例对象且左边不是实例对象时,Python 才会调用 ​​__radd__​​

class Computer: def __init__(self, val): self.val = val def __add__(self, other): print("add", self.val, other) return self.val + other def __radd__(self, other): print("radd", self.val, other) return other + self.valx = Computer("Dell")y = Computer("Mac")z = x + yprint("x + y =", z)

注意:​​__radd__​​ 中的顺序反转,self 变成在 + 的右侧,而 other 在左侧。

运行结果:

('add', 'Dell', <__main__.Computer instance at 0x10b4fed70>)('radd', 'Mac', 'Dell')('x + y =', 'DellMac')

以下同理:

class sample: def __init__(self, a): self.a = a def __add__(self, other): return self.a + other.a def __radd__(self, other): return other.a + self.aOb1 = sample("test")Ob2 = sample("Operator")Ob3 = Ob2 + Ob1print(Ob3)# testOperator

在 __radd__ 中重用 __add__

为了得到没有使用位置限制的真正可对易运算符,有时候只需要重用 ​​__add__​​​ 来实现 ​​__radd__​​ :

class Computer2: def __init__(self, val): self.val = val def __add__(self, other): return self.val + other def __radd__(self, other): return self.__add__(other)

class Computer3: def __init__(self, val): self.val = val def __add__(self, other): return self.val + other def __radd__(self, other): return self + other class Computer4: def __init__(self, val): self.val = val def __add__(self, other): return self.val + other __radd__ = __add__

在这些例子中,位于加号右侧的实例出发单一且共享的 ​​__add__​​ 方法,并将右侧操作数传递给 self,从而能像左侧时一样被处理。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python 一网打尽<排序算法>之从希尔排序算法的分治哲学开始(python和java哪个更值得学)
下一篇:聊聊maven的pom.xml中的exclusions标签的作用
相关文章

 发表评论

暂时没有评论,来抢沙发吧~