朋友们,如需转载请标明出处:https://blog.csdn.net/jiangjunshow
声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!由于这套python教程不是由我所写(有时候有空也会参与编写),所以不如我的人工智能教程风趣幽默,学起来比较枯燥;但它的知识点还是讲到位的了,也值得阅读!想要学习AI技术的同学可以看我的人工智能教程https://blog.csdn.net/jiangjunshow/article/details/77338485。PS:看不懂本篇文章的同学请先看前面的文章,循序渐进每天学一点就不会觉得难了!
什么是运算符重载?这可能也是一个使不少程序员感到迷茫的知识点。今天,我试试来给大家慢慢讲解一下,看能不能讲清楚,有点啰嗦的话你不要烦躁哦!
假设我们定义了一个字符串变量a='abc',然后再定义一个变量b=a+'xyz',那么运算符+号会将'abc'和'xyz'连接起来赋值给b,也就是说b变成了'abcxyz'。这个知识点一般同学们都知道。但是,如果我们定义一个类ThirdClass,并将 a = ThirdClass('abc'),然后又将b=a+'xyz',那么这时b变成什么了呢?这个问题一两句话回答不清楚,下面我慢慢给大家讲解。
我们先把ThirdClass类给定义出来,如下面代码所示。里面的init方法是用来接收初始化参数的,也就是前面那行代码a = ThirdClass('abc')中的'abc'会传到这个init方法的value中。init方法对应的就是初始化操作。这个方法现在不是我们的重点,我们的重点在第二个方法,也就是add方法。这个方法对应的就是运算符加号+的操作。也就是说,上面那行代码b=a+'xyz'会触发对add方法的调用,并且'xyz'会传到add方法的other参数中。如下面代码所示,这个方法中会将init接收的'abc'与other参数中的'xyz'连接起来,然后再用字符串'abcxyz'来构建一个新的ThirdClass对象。有些绕,不懂没有关系,继续往下看!
>>> class ThirdClass():
... def __init__(self,value):
... self.data = value
... def __add__(self,other):
... return ThirdClass(self.data + other)
... def display(self):
... print('Current value = "%s"' % self.data)
上面的代码定义好了ThirdClass类。下面的代码先用字符串'abc'构建了一个ThirdClass类的对象a,然后调用a对象的display方法将对象内的data数据值'abc'显示出来。后面又让对象a与字符串'xyz'相加,运算符+号触发了a对象的add方法,这个方法内部会利用连接好的字符串'abcxyz'来构建一个新的ThirdClass对象,并将这个对象返回并赋值给变量b。好,现在时机成熟了,我们可以回答文章开头提出的问题了——b变成了一个ThirdClass对象,这个对象内部的值是'abcxyz'。
>>> a = ThirdClass('abc') # __init__ called
>>> a.display()
Current value = "abc"
>>> b = a + 'xyz' # __add__: makes a new instance
>>> b.display() # b has all ThirdClass methods
Current value = "abcxyz"
上面向大家展示的就是一个简单的运算符重载的例子,它对运算符加号+进行了重载。
为什么叫做“运算符重载”呢?因为本来加减乘除等运算符是为内置类型服务的,例如文章开头处的字符串变量就是内置类型,加号会将两个字符串变量连接成一个字符串。如果我们自己定义的类想要使用这些运算符,那么就需要对这些运算符进行重载。
Python对运算符的重载是通过在类里面添加特殊方法来实现的。这些特殊方法都是以双下划线来命名的。例如我们上面看到的add方法。Python为每种运算符和特殊命名方法之间,定义了一对一的映射关系。例如你在类里面定义了一个add方法,那么就对加号运算符进行了重载。当这个类的对象遇到了加号+时就会自动调用类里面的add方法了。如果添加了 sub方法,那么就对减号-运算符进行了重载。
下面我将Python里面的运算符重载方法都给大家列出来了,方便大家以后查阅!觉得文章还行的话帮忙点个不要钱的赞!
一、算术运算符
__add__(self, other) ➕ 加法( + )
__sub__(self, other) ➖ 减法( - )
__mul__(self, other) ✖️ 乘法( * )
__truediv__(self, other) ➗ 真除法( / ,返回浮点数)
__floordiv__(self, other) 🧮 整除( // ,返回整数)
__mod__(self, other) 🔍 取模( % )
__pow__(self, other, modulo) ⚡ 幂运算( ** )
__divmod__(self, other) ↔️ 返回 (商, 余数) ( divmod() 函数)
二、比较运算符
__eq__(self, other) ⚖️ 相等( == )
__ne__(self, other) ≠ 不等( != )
__lt__(self, other) < 小于( < )
__le__(self, other) ≤ 小于等于( <= )
__gt__(self, other) > 大于( > )
__ge__(self, other) ≥ 大于等于( >= )
三、位运算符
__lshift__(self, other) ⬅️ 左移( << )
__rshift__(self, other) ➡️ 右移( >> )
__and__(self, other) & 按位与( & )
__or__(self, other) 按位或( | )
__xor__(self, other) ^ 按位异或( ^ )
__invert__(self) ~ 按位取反( ~ )
四、增量赋值运算符
__iadd__(self, other) ➕ 加法赋值( += )
__isub__(self, other) ➖ 减法赋值( -= )
__imul__(self, other) ✖️ 乘法赋值( *= )
__itruediv__(self, other) ➗ 真除赋值( /= )
__ifloordiv__(self, other) 🧮 整除赋值( //= )
__imod__(self, other) 🔍 取模赋值( %= )
__ipow__(self, other) ⚡ 幂赋值( **= )
五、容器操作
__len__(self) 📏 返回长度( len() )
__getitem__(self, key) 🔑 索引访问( obj[key])
__setitem__(self, key, value) ✍️ 索引赋值( obj[key] = value )
__delitem__(self, key) ❌ 删除元素( del obj[key] )
__contains__(self, item) 🔍 包含检查( item in obj )
__iter__(self) 🔄 返回迭代器( for x in obj )
六、类型转换与显示
__str__(self) 📝 用户友好字符串( str(obj) , print(obj) )
__repr__(self) 💻 官方字符串表示( repr(obj) ,调试用)
__int__(self) 🔢 转为整数( int(obj) )
__float__(self) 🎯 转为浮点数( float(obj) )
__bool__(self) ✔️ 布尔值( bool(obj) ,默认调用 __len__ )
__bytes__(self) 🔣 字节表示( bytes(obj) )
七、其他特殊方法
__call__(self, *args, kwargs) 📞 使对象可调用( obj() )
__new__(cls, *args, kwargs) 🏗️ 控制实例创建(在 __init__ 前调用)
__enter__(self) , __exit__(self, ...) 🚪 上下文管理( with obj: )
__copy__(self) , __deepcopy__(self, memo) 📋 控制浅拷贝/深拷贝( copy 模块)