本帖最后由 Ensoleile 于 2023-1-10 00:34 编辑
运算相关的魔法方法(上)P163class S(str):
def __add__(self, other):
return len(self) + len(other)
s1 = S('FishC')
s2 = S('python')
print(s1 + s2)
#11
print('FishC' + s2)#FishCpython
print(s1 + 'python')#11
#从__add__()魔法方法的原型也可以看出端倪,加号左边的对象是self指自己,右边对象other指别人,s1 + s2相当于s1.__add__(s2)
#__radd__()方法调用前提:当两个对象相加的时候,如果左侧的对象和右侧的对象不同类型,并且左侧的对象没有定义__add__()方法,或者其__add__()返回NotImplemented,那么python就会去右侧的对象中查找是否有__radd__()方法的定义
class S1(str):
def __add__(self, other):
return NotImplemented#返回NotImplemented表示该魔法方法是未实现的
class S2(str):
def __radd__(self, other):
return len(self) + len(other)
s1 = S1('apple')
s2 = S2('banana')
print(s1 + s2)#11
#成功调用s2的__radd__()方法。①s1和s2两个是基于不同类的对象,②且s1里不能实现__add__()方法,否则还是会优先执行左侧对象的__add__()方法(如果s1不写__add__()方法也可以实现)
#增强赋值运算:执行运算兼赋值的操作,s1.__iadd__(s2)相当于s1 += s2
class S1(str):
def __iadd__(self, other):
return len(self) + len(other)
s1 = S1('apple')
s1 += s2
print(s1, type(s1), sep=' ')#11 <class 'int'>
#如果增强赋值运算符的左侧对象没有实现相应的魔法方法,如+=左侧对象没有实现__iadd__()方法,那么python就会退而求其次使用__add__()方法和__radd__()方法来替代
print(s2, type(s2), sep='***')#banana***<class '__main__.S2'>
s2 += s2
print(s2, type(s2), sep='***')#bananabanana***<class 'str'>
#+=两侧都是s2为同一类,所以不能调用__radd__()方法,而是去父类str中查找__add__()方法
#魔法方法不仅能拦截运算符,也可以拦截发生在对象的内置函数
class ZH_INT:
def __init__(self, num):
self.num = num
def __int__(self):
try:
return int(self.num)
except ValueError:
zh = {'零':0, '一':1, '二':2, '三':3, '四':4, '五':5, '六':6, '七':7, '八':8, '九':9, '壹':1, '贰':2, '叁':3, '肆':4, '伍':5, '陆':6, '柒':7, '捌':8, '玖':9}
result = 0
for each in self.num:
if each in zh:
result += zh[each]
else:
result += int(each)
result *= 10
return result // 10
n = ZH_INT('520')
print(int(n))#520
n = ZH_INT(3.14)
print(int(n))#3
n = ZH_INT('五贰零')
print(int(n))#520
n = ZH_INT('五贰零1314')
print(int(n))#5201314
|