Python基础学习教程:高级函数
异常捕获
Python中,使用try+catch两个关键字来实现对异常的处理。在我们平时的工作中,异常的出现是在所难免的,但是异常一旦出现,极有可能会直接导致程序崩溃,无法正常运行,所以异常一定要及时的做出对应的处理。
示例:try+catch捕获整数不能为0的异常。
try:
a = 1 / 0
print(a)
except Exception as e:
print("出错了:", e)
抛出异常
我们可以通过raise方法,主动抛出异常。比如参数不正确或者缺少必填参数,导致方法无法继续往下执行的时候,我们可以考虑这么使用。不过,抛出异常是下下之策,因为一旦调用者没有捕获,整个程序就会崩溃,在真实的开发中,一定要慎用。
示例:抛出异常。在这个案例中,我们定义了一个div方法,用来求两个数相除的结果。同时,我们对被除数b做了校验,如果b为0,我们会抛出异常信息。
def div(a, b):
if b == 0:
raise "被除数不能为0"
return a / b
if __name__ == '__main__':
print(div(20, 2))
print(div(20, 0))
迭代器
在了解迭代器之前,我们先了解什么是可迭代对象。可迭代对象指的是可以通过for去遍历的对象。迭代器就是一种可以被遍历的对象,通常需要实现iter和next两个基本方法。需要注意的是,可迭代对象不一定是迭代器,但是迭代器一定是可迭代对象。
迭代器从集合的第一个元素开始访问,直到所有的元素被访问完毕。迭代器只能从前往后遍历,不能从后往前遍历,这点和range函数和列表很不同 。
示例:通iter方法,可以将列表转换为迭代器。
arr = [1, 2, 3]
iarr = iter(arr)
print(type(iarr), iarr)
# 取出数据
print(next(iarr))
print(next(iarr))
print(next(iarr))
示例:自定义一个迭代器。一个自定义的迭代器类,必须要实现__iter__和__next__方法,其中__next__方法是最重要的,用于指定每次迭代要返回的值。在这个案例中,我们演示了分别使用for循环和while循环遍历迭代器,一定要注意退出条件,已经迭代器迭代完毕以后,要么是抛出异常,要么是返回None,如果不做退出的判断,很可能会导致程序异常崩溃。
class A:
def __init__(self, n):
self.n = n
self.count = -1 # 计数器
def __iter__(self):
"""必须实现"""
# 返回可迭代对象
return self
def __next__(self):
"""必须实现"""
# 返回每一次迭代器计算出的结果
# 调用next会自动执行此方法
if self.count < self.n - 1:
self.count += 1
return self.count
return None
if __name__ == '__main__':
# 创建可迭代对象
a = A(3)
# while 遍历
while True:
v = next(a)
if v is not None:
print(v)
else:
break
# for 遍历
a = A(3)
for i in a:
if i is None:
break
print(i)
生成器
生成器和迭代器类似,都是用来提供遍历的一种特殊数据结构。生成器不会占用大量的内存,只在遍历的时候会占用生成值的内存,所以在处理大量数据的时候,如果需要节约内存,一般都建议使用生成器来替代列表。生成器的特点是使用yield关键字来返回值。
示例:简单的生成器。
def colors():
"""一个简单的生成器函数"""
for color in ["black", "red", "green", "yellow", "blue"]:
yield color
if __name__ == '__main__':
# 生成器可以直接用for遍历
for color in colors():
print(color)
装饰器
装饰器是一种基于闭包的高级函数,一般是用来装饰函数或者类的方法,能够在函数的执行前后执行特殊的逻辑。比较常见的有记录日志,统计方法的执行时间等。也可以用来做权限校验等其他高级的操作。
示例:一个简单的装饰器。在这个装饰器中,我们对testf方法进行了装饰,并统计了这个方法执行需要消耗的时间。这里要注意,spendtime有一个f的参数,而内部方法inner使用了这个参数,f实际上是被装饰的方法。
import time
def spendtime(f):
"""一个统计方法执行时间的装饰器"""
def inner():
"""接收外部的变量f,f本质上是一个函数"""
print("方法执行之前")
start = time.time()
f() # 执行方法
print("方法执行之后,统计消耗时间:", time.time() - start)
return inner
@spendtime # 使用装饰器
def testf():
"""测试方法"""
time.sleep(3)
print("测试方法执行了。。。")
if __name__ == '__main__':
# 调用被装饰的方法
testf()