Python中的数学运算操作符使用进阶
Python中对象的行为是由它的类型 (Type) 决定的。所谓类型就是支持某些特定的操作。数字对象在任何编程语言中都是基础元素,支持加、减、乘、除等数学操作。 这里通过实现一个具有支持加法运算的中文数字类说明如何在Python中实现一个支持常见的数学操作。ChineseNumber类的基本定义如下。 class ChineseNumber: def __init__(self,n): self.num = n self.alphabet = [u'零',u'一',u'二',u'三',u'四',u'五',u'六',u'七',u'八',u'九',u'十'] def __str__(self): sign = '负' if self.num < 0 else '' return sign + ''.join([self.alphabet[int(s)] for s in str(abs(self.num))]) def __repr__(self): return self.__str__() 目前,实现的效果是这样的: >>> a = ChineseNumber(2) >>> a #调用a.__repr__() 二 >>> print(a) #调用a.__str__() 二 一般数学操作符 def __add__(self,other): if type(other) is ChineseNumber: return ChineseNumber(self.num + other.num) elif type(other) is int: return ChineseNumber(self.num + other) else: return NotImplemented 这时ChineseNumber的对象就可以使用+了。 >>> a,b = ChineseNumber(2),ChineseNumber(10) >>> a + b 十二 >>> a + 5 七 >>> a + 3.7 TypeError: unsupported operand type(s) for +: 'ChineseNumber' and 'float' 对于+,a + b相当于调用a.__add__(b). 类似地,可以定义其他数学操作符,见下表。 object.__add__(self,other): + object.__sub__(self,other): - object.__mul__(self,other): * object.__matmul__(self,other): @ object.__truediv__(self,other): / object.__floordiv__(self,other): // object.__mod__(self,other): % object.__divmod__(self,other): divmod,divmod(a,b) = (a/b,a%b) object.__pow__(self,other[,modulo]): **,pow() object.__lshift__(self,other): << object.__rshift__(self,other): >> object.__and__(self,other): & object.__xor__(self,other): ^ object.__or__(self,other): | 操作数反转的数学操作符 (Reflected/Swapped Operand) >>> 2 + a TypeError: unsupported operand type(s) for +: 'int' and 'ChineseNumber' 2是整数类型,它的__add__()方法不支持ChineseNumber类的对象,所以出现了上述错误。定义操作数反转的数学操作符可以解决这个问题。给ChineseNumber类添加__radd__()方法,实现操作数反转的+运算。 def __radd__(self,other): return self.__add__(other) 对于a + b,如果a没有定义__add__()方法,Python尝试调用b的__radd__()方法。此时,a + b相当于调用b.__radd__(a)。 >>> a = ChineseNumber(2) >>> 2 + a 四 类似地,可以定义其他操作数反转的数学操作符,见下表。 object.__radd__(self,other): + object.__rsub__(self,other): - object.__rmul__(self,other): * object.__rmatmul__(self,other): @ object.__rtruediv__(self,other): / object.__rfloordiv__(self,other): // object.__rmod__(self,other): % object.__rdivmod__(self,b) = (b/a,b%a) object.__rpow__(self,pow() object.__rlshift__(self,other): << object.__rrshift__(self,other): >> object.__rand__(self,other): & object.__rxor__(self,other): ^ object.__ror__(self,other): | 运算赋值操作符 def __iadd__(self,other): if type(other) is ChineseNumber: self.num += other.num return self elif type(other) is int: self.num += other return self else: return NotImplemented 此时, >>> a,ChineseNumber(10) >>> a += b >>> a 十二 >>> a + 7 >>> a 十九 类似地,可以定义其他运算赋值操作符,见下表。 object.__iadd__(self,other): += object.__isub__(self,other): -= object.__imul__(self,other): *= object.__imatmul__(self,other): @= object.__itruediv__(self,other): /= object.__ifloordiv__(self,other): //= object.__imod__(self,other): %= object.__ipow__(self,modulo]): **= object.__ilshift__(self,other): <<= object.__irshift__(self,other): >>= object.__iand__(self,other): &= object.__ixor__(self,other): ^= object.__ior__(self,other): |= 一元数学操作符 def __neg__(self): return ChineseNumber(-self.num) 此时,ChineseNumber对象就支持-操作了。 >>> a = ChineseNumber(5) >>> -a 负五 其他一元运算符见下表。 object.__neg__(self): - object.__pos__(self): + object.__abs__(self): abs() object.__invert__(self): ~ object.__complex__(self): complex() object.__int__(self): int() object.__float__(self): float() object.__round__(self): round() object.__index__(self): operator.index() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |