Using __iadd__ & __radd__

# Right-Side and In-Place Uses: __radd__ and __iadd__
# Why we need Right-Side Addition
>>> class Adder:
...     def __init__(self, value=0):
...             self.data = value
...     def __add__(self, other):
...             return self.data + other
...
>>> x = Adder(5)
>>> x + 2
7
>>> 2 + x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'Adder'
>>>

# Add __radd__
>>> class Commuter:
...     def __init__(self, val=0):
...             self.data = val
...     def __add__(self, other):
...             print('add', self.data, other)
...             return self.data + other
...     def __radd__(self, other):
...             print('radd', self.data, other)
...             return other + self.data
...
>>> x = Commuter(99)
>>> x + 1
add 99 1
100
>>> 1 + x
radd 99 1
100
>>> y = Commuter(100)
>>> x + y
add 99 <__main__.Commuter object at 0x0075B090>
radd 100 99
199
>>>

# Reusing __add__ in __radd__
class Commuter1:
    def __init__(self, val=0):
        self.data = val
    def __add__(self, other):
        return self.data + other
    def __radd__(self, other):
        return self.__add__(other)  # Call __add__ explicitly

class Commuter2:
    def __init__(self, val=0):
        self.data = val
    def __add__(self, other):
        return self.data + other
    def __radd__(self, other):
        return self + other         # Swap order and re-add

class Commuter3:
    def __init__(self, val=0):
        self.data = val
    def __add__(self, other):
        return self.data + other
    __radd__ = __add__              # Alias: cut out the middleman

# Propagating class type
>>> class Commuter:
...     def __init__(self, val=0):
...             self.data = val
...     def __add__(self, other):
...             return Commuter(self.data + other)  # What if return self.data + other directly ??
...     def __radd__(self, other):
...             return Commuter(other + self.data)
...     def __str__(self):
...             return '<Commuter: %s>' % self.data
...
>>> x = Commuter(2)
>>> y = Commuter(3)
>>> print(x)
<Commuter: 2>
>>> print(x + y)
<Commuter: <Commuter: 5>>
>>> z = x + y
>>> print(z)
<Commuter: <Commuter: 5>>
>>> print(z + x + y)
<Commuter: <Commuter: <Commuter: <Commuter: 10>>>>
>>>

# Add type-test to avoid object nested
>>> class Commuter:
...     def __init__(self, val=0):
...             self.data = val
...     def __add__(self, other):
...             if isinstance(other, Commuter):
...                 other = other.val
...             return Commuter(self.data + other)
...     def __radd__(self, other):
...             return Commuter(other + self.data)
...     def __str__(self):
...             return '<Commuter: %s>' % self.data
...
>>> x = Commuter(2)
>>> y = Commuter(3)
>>> print(x)
<Commuter: 2>
>>> print(x + y)
<Commuter: 5>
>>> z = x + y
>>> print(z)
<Commuter: 5>
>>> print(z + x + y)
<Commuter: 10>
>>>

# In-Place Addition +=
# To also implement += in-place augmented addition, code either an __iadd__ or an __add__
# The __iadd__ runs often more efficient for in-place changes,
# though __add__ also support in-place changes
>>> class Number:
...     def __init__(self, val):
...             self.data = val
...     def __iadd__(self, other):
...             self.data += other
...             return self
...
>>> x = Number(5)
>>> x += 1
>>> x += 1
>>> x.data
7
>>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值