Python--未实现和未实现异常、运算符重载反向算法

未实现和未实现异常

print(type(NotImplemented))
print(type(NotImplementedError))

# 
# 

# raise NotImplemented # TypeError: exceptions must derive from BaseException
raise NotImplementedError # NotImplementedError

NotImplemented是个值,单值,是NotImplementedType的实例
NotImplementedError是类型,是异常类,返回type

运算符重载中的反响方法

class A:
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        print(self, 'add')
        return self.x + other.x

    def __iadd__(self, other):
        print(self, 'iadd')
        return A(self.x + other.x)

    def __radd__(self, other):
        print(self, 'radd')
        return self.x + other.x
a = A(4)
a + 1
  • 运行结果
    Python--未实现和未实现异常、运算符重载反向算法_第1张图片
    出现了AttributeError,因为1是int类型,没有x这个属性,A类的__add__被执行了

  • 测试1 + a ,运行结果如下
    Python--未实现和未实现异常、运算符重载反向算法_第2张图片
    这次执行的是实例a的__radd__方法
    1 + a等价于1.__add__(a),也就是int.__add__(1, a),而int类型实现了__add__方法,没有抛出异常,而是执行了实例a的__radd__方法

  • 分析下面例子代码

class A:
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        print(self, 'add')
        return self.x + other.x

    def __iadd__(self, other):
        print(self, 'iadd')
        return A(self.x + other.x)

    def __radd__(self, other):
        print(self, 'radd')
        return self.x + other.x

class B: # 未实现__add__
    def __init__(self, x ):
        self.x = x
a = A(4)
b = B(10)
print(a + b)
print(b + a)

# 执行结果
<__main__.A object at 0x0000021577038400> add
14
<__main__.A object at 0x0000021577038400> radd
14

b + a 等价于b.__add__(a),但是类B没有实现__add__方法,反而去找a的__radd__方法
1 + a等价于1.__add__(a),而int类型实现了__add__方法,不过这个方法对于这种加法的返回值是NotImplemented,解释器发现是这个值,就会发起对第二操作对象的__radd__方法的调用

  • B类也等价于下面的实现
class B:
    def __init__(self, x ):
        self.x = x

    def __add__(self, other):
        if isinstance(other, type(self)):
            return self.x + other.x
        else:
            return NotImplemented
  • 1 + a 用如下方法解决
class A:
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        print(self, 'add')
        if hasattr(other, 'x'):
            return self.x + other.x
        else:
            try:
                x = int(other)
            except:
                x = 0
            return self.x + x

    def __iadd__(self, other):
        print(self, 'iadd')
        return A(self.x + other.x)

    def __radd__(self, other):
        print(self, 'radd')
        return self + other

class B:
    def __init__(self, x):
        self.x = x

a = A(4)
b = B(20)
print(a + b)
print(b + a)
print(a + 2)
print(2 + a)

# 执行结果
<__main__.A object at 0x000001C4AA548400> add
24
<__main__.A object at 0x000001C4AA548400> radd
<__main__.A object at 0x000001C4AA548400> add
24
<__main__.A object at 0x000001C4AA548400> add
6
<__main__.A object at 0x000001C4AA548400> radd
<__main__.A object at 0x000001C4AA548400> add
6

'abc' + a , 字符串也实现了__add__方法,不过默认是处理不了和其他类型的加法,就返回NotImplemented

Python--未实现和未实现异常、运算符重载反向算法_第3张图片

你可能感兴趣的:(Python--未实现和未实现异常、运算符重载反向算法)