魔法函数是Python中的特性,学习好魔法函数将有助于我们写出优秀的pythonic(优雅的、地道的、整洁的)代码,同时因为Python语言的特性,我们在进行框架设计的时候除了设计模式等高级技能,魔法函数是必须使用的,因此学习好魔法函数是Python语言进阶的必经之路。下面我们就为大家介绍Python里的常用魔法函数。
常用魔法函数(非数学运算类型)
字符串表示
__repr__
__str__
本来是写了一些例子来说明这两个函数,但是后来发现没什么用,我们在工作中用到的也就是打印显示print(item)和将对象转换为字符串str(item),因此没必要占用这么大的篇幅,这里简单说一下需要注意的用法。
如果我们在一个类中同时定义了__str__和__repr__函数,print和str函数会调用__str__,但是如果对象在列表内,打印时始终会调用__repr__,如果只定义了__repr__,那么print、str都会调用__repr__,所以强烈建议在写类的时候,如果需要格式化输出,那么一定要定义一个__repr__函数。
集合序列相关
__len__
这个很简单,计算对象的长度, 我们自己定义的如果要计算长度一定要定义__len__函数,当然你也可以定义一个getLength函数来供调用,但是我们要知道内置对象,如列表、字典调用len()函数的时候,内部并不是遍历,而是直接获取对象长度,因此我们强烈推荐重写__len__函数来计算对象的长度,Python内部会做一定的优化。
__getitem__
__setitem__
__delitem__
结合上面的代码和输出结果可以知道,这三个函数就是把我们的对象变成可切片操作的对象,我们可以使用Python所支持的各种切片操作
__contains__
这将使我们能使用in操作符来判断取值是否在对象中,而不是写一个函数去调用
迭代相关
__iter__
__next__
这两个是比较有用的魔法函数,当我们想要使用for...in...来遍历一个对象时,必须要使用一个可迭代对象,但是我们自己定义的类并不是一个可迭代的类,实现以上两个方法后,就变成了可迭代类。
可以看到,直接用for循环来遍历这个对象,这里注意三点,第一是__iter__函数要返回对象自身,因为for...in...需要一个可迭代对象,而不是迭代器,因此我们必须给它一个实际对象,__iter__几乎总是返回自身对象;第二是在__next__函数中如果迭代完成,必须返回一个StopIteration的异常,而for...in...会自动捕获这个异常,并结束循环;第三是请注意我写了两次循环遍历,这里有一个容易被忽略的问题,当迭代完成后,我们必须将迭代的条件设为初始值,否则在第二次循环时就无法正常执行遍历。当然对于上面的这种循环迭代方式,还有另外一种实现:
输出结果是一致的,这是由Python帮我们优化的,如果找不到可迭代对象,就会去找__getitem__函数,但是这两个是不一样的,对于上面的两个类,如果判断它们是不是迭代对象,那么只有实现了__iter__和__next__函数的才会被判断为迭代对象
因此我们要根据实际情况来使用
可调用
__call__
这个魔法函数可以将实例对象变为像函数一样的可调用对象。在举这个例子之前我们先简单了解一下装饰器
你没看错,这就是最简单的一个装饰器,装饰器的本质就是一个调用对象返回了一个可调用对象,一定要记住这一句。函数本身是一个可调用对象,如果返回一个可调用对象,那么它就是装饰器。你记住了上面那一句,我们再来看一下下面的例子:
代码看起来很简单,注释很懵逼,实际上你只要记住装饰器的本质就行了,这有助于我们实现更复杂的装饰器,万变不离其宗嘛。
with上下文管理器
__enter__
__exit__
上下文管理器有助于我们处理文件或其他资源句柄的申请释放,防止我们忽略释放资源句柄导致的异常。
从输出可以看出,即使内部执行报错,申请和释放总是会被执行,但是要注意在__enter__和__exit__函数中一定不能出错
数值转换
__abs__
__bool__
__int__
__float__
__hash__
这个分组内我们只说一下__hash__,其他的见名知意就不说了,我们先看下面的例子
报错告诉我们list不是一个可哈希的类型,大家应该知道在Python中,字典的键必须是一个可哈希的对象,因为Python中的字典背后的实现是采用的哈希表,但是list对象是不能哈希的,自然就报错了,下面我们做一下修改:
奇迹的发现,list可以作为键了,因为我们重载了list,实现了哈希函数,这样就满足了字典的要求
还有一些其他的魔法函数,我们下次再总结,Python中的魔法函数非常多,我们不需要全部记下,大概有个印象就可以了。记住几个常用的模块:属性、元类、集合序列、上下文。
领取专属 10元无门槛券
私享最新 技术干货