运算符重载 operator overload
作用:
让自定义的对象(实例) 象内建对象一样进行运算符操作
让程序简洁易读
说明:
运算符重载方法的参数已经有固定的含义,不建议改变原意义
算术运算符:
加法 + ===> __add__(self, other) 方法
减法 - ===> __sub__(self, other) 方法
乘法 * ===> __mul__(self, other) 方法
除法 / ===> __truediv__(self, other) 方法
地板除 // ===> __floordiv__(self, other) 方法
取模(求余) % ===> __mod__(self, other) 方法
幂 ** ===> __pow__(self, other) 方法
![](https://i-blog.csdnimg.cn/blog_migrate/f937e701cf3ffedd7a144a4c40dd58c6.png)
反向算术运算符的重载:
__radd__(self, lhs) 加法 lhs + self
__rsub__(self, lhs) 减法 lhs - self
__rmul__(self, lhs) 乘法 lhs * self
__rtruediv__(self, lhs) 除法 lhs / self
__rfloordiv__(self, lhs) 地板除法 lhs // self
__rmod__(self, lhs) 求余 lhs % self
__rpow__(self, lhs) 幂 lhs ** self
lhs (left hand side) 左手边
![](https://i-blog.csdnimg.cn/blog_migrate/b7a73c98657d787a64984137c468699f.png)
复合赋值运算符重载
__iadd__(self, other) 加法 self += other
__isub__(self, other) 减法 self -= other
__imul__(self, other) 乘法 self *= other
__itruediv__(self, other) 除法 self /= other
__ifloordiv__(self, other)地板除 self //= other
__imod__(self, other) 求余 self %= other
__ipow__(self, other) 幂 self **= other
作用:
用来替代默认的 算术运算符 __add__ 等方法调用
![](https://i-blog.csdnimg.cn/blog_migrate/5ce8f0584bfcd4fe8d6b2a87e5ed8596.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2036b3531965cf203bbba24c1d232ff1.png)
一元运算符的重载:
__neg__ 负号 -
__pos__ 正号 +
__invert__ 取反 ~
语法:
def __xxx__(self):
....
![](https://i-blog.csdnimg.cn/blog_migrate/05abc99ab7e5c9c90f9b5da565b607e8.png)
比较运算符的重载:
__lt__ 小于 <
__le__ 小于等于 <=
__gt__ 大于 >
__ge__ 大于等于 >=
__eq__ 等于 ==
__ne__ 不等于 !=
注:
比较运算符通常返回布尔值 True或 False
![](https://i-blog.csdnimg.cn/blog_migrate/d8e6236b126ccc1827df988cc7573925.png)
位运算符重载:
__and__ 位与 &
__or__ 位或 |
__xor__ 位异或 ^
__lshift__ 左移 <<
__rshift__ 右移 >>
__invert__ 取反 ~
反向位运算
__rand__
__ror__
__rxor__
__rlshift__
__rrshift__
复合赋值位运算重载
__iand__ 位与 &=
__ior__ 位或 |=
__ixor__ 位异或 ^=
__ilshift__ 左移 <<=
__irshift__ 右移 >>=
s1 = OrderSet([1,2,3,4])
s2 = OrderSet([3,4,5])
print(s1 & s2) # OrderSet([3,4])
print(s1 | s2) # OrderSet([1,2,3,4,5])
print(s1 - s2) # OrderSet([1,2])
print(s1 ^ s2) # OrderSet([1,2,5])
if OrderSet([1,2,3]) != OrderSet([1,2,3,4])
print("不相等")
# 思考是否可以实现以下操作?
if 2 in s1:
print("2 在 s1 内")
in/ not in 运算符的重载
格式:
def __contains__(self, e:"元素"):
....
ex:
![](https://i-blog.csdnimg.cn/blog_migrate/82ee2bb313d8c65d26a518b7cc632263.png)
示意:
L = [1,2,3,4]
3 in L
100 not in L
索引和切片运算符的重载
重载方法:
__getitem__(self, i): # 用索引/切片取值
__setitem__(self, i, v) # 用索引/切片赋值
__delitem__(self, i) # 用del 语句删除索引或切片操作
作用:
让自定义类型的对象支持索引和切片操作
![](https://i-blog.csdnimg.cn/blog_migrate/67425e6d24770fc986f5afb36b71d01d.png)
切片运算符的重载:
类 slice
数据:
slice.start 切片的起始索引
slice.stop 终止索引
slice.step 步长
运算符重载:
+ - * / // % ** # __add__, __iadd__, __radd__
< <= > >= == != # __lt__ ...
+ (正号) -(负号) ~(取反) __pos__
位运算: << >> & | ^, ~ # __and__, __rand__, __iand__
in /not in # __contains__
[] [:] [::] # __setitem__, __getitem__,__delitem__
迭代器(高级篇)
什么是迭代器
可以通过next() 函数取值的对象,就是迭代器
迭代器协议:
迭代器协议是指对象能够使用next函数获取下一项数据,在没有下一项数据时,触发一个StopIteration 异常来终止迭代的约定
迭代器协议的实现方法:
__next__(self) 方法来实现迭代器协议
![](https://i-blog.csdnimg.cn/blog_migrate/9ad72c9c4cfe6d5e6f88120a6e38d028.png)
什么是可迭代对象:
指能用iter(obj) 函数返回迭代器的对象(实例)
iter(obj) 对应的方法是 __iter__(self), 来返回迭代器对象
异常(高级篇)
with 语句
语法:
with 表达式1 [as 变量1], 表达式2[as 变量2], ...
语句块
作用:
使用于对资源进行访问的场合.确保使用过程中不管是否发生异常,都会执行必要有"清理"操作,并释放资源
例如文件的使用后自动关闭, 线程中锁的自动获取和释放等.
1. 先执行 表达式 用 as 子句中的变量绑定生成的对象,然后执行with语句内部的部分
2. with 语句同 try-finally类似,它不会改变异常的状态
环境管理器:
类内有__enter__ 和 __exit__方法的类被称为环境管理器
能够用with语句进行管理的对象必须是环境管理器
__enter__ 将在进入with语句时被调用并返回由 as 变量绑定的对象
__exit__ 将在离开with语句时被调用,且可以用参数来判断离开with语句时是否有异常状态
![](https://i-blog.csdnimg.cn/blog_migrate/74d5b0d0420327d053705e10edbd04b6.png)