未实现和未实现异常
print(type(NotImplemented))
print(type(NotImplementedError))
# <class 'NotImplementedType'>
# <class 'type'>
# 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
-
运行结果
出现了AttributeError,因为1是int类型,没有x这个属性,A类的__add__
被执行了 -
测试
1 + a
,运行结果如下
这次执行的是实例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