装饰器
定义
装饰器是一个函数,主要作用是用来包装另一个函数或类,包装的目的是在不改变原函数(或类名)的情况下改变被包装对象的行为。简单来说就是在不改变原函数(或类名)的情况下,给函数增加新的功能。
装饰器是一个函数,传入的是一个函数,返回的是一个函数。
语法:
def 装饰器函数名(参数):
语句块
return 函数对象
@装饰器函数名
def 函数名(形参列表):
语句块1
2
3
4
5
6
7
原理:
被装饰函数的变量(函数名)绑定装饰器函数调用后的返回的函数。
#高阶函数+内嵌函数=装饰器函数
#以下定义一个计算时间的装饰器函数
import time
def demo(fun):
def wrapper():
start_time = time.time()
fun()
end_time = time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" %execution_time )
return wrapper
@demo
def fun():
print("hello",end='')
time.sleep(1)
print(" world!")
if __name__ == '__main__':
fun()
运行结果为:
hello world!
time is 1001 ms1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
这里的demo函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数fun()就在返回函数wrapper()的内部执行。然后在函数fun()前面加上@demo,fun()函数就相当于被注入了计时功能,现在只要调用fun(),它就已经变身为“新的功能更多”的函数了。
迭代器
定义
迭代器是访问可迭代对象的工具。
迭代器是指用iter(obj) 函数返回的对象(实例)。
迭代器可以用next(it) 函数获取可迭代对象的数据。
迭代器函数 iter和next
iter(iterable) 从可迭代对象中返回一个迭代器,iterable 必须是能提供一个迭代器的对象。
next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIterator异常。
说明:
迭代器只能往前取值,不会后退
用iter函数可以返回一个可迭代对象的迭代器
示例如下:
L = [1, 3, 5, 7]
it = iter(L) # 让L提供一个能访问自己的迭代器
next(it) # 1 从迭代器中取值,让迭代器去获取L中的一个元素
next(it) # 3
next(it) # 5
next(it) # 7
next(it) # StopIteration 异常1
2
3
4
5
6
7
迭代器的用途
用迭代器可以依次访问可迭代对象的数据。
示例如下:
#以下用for循环来访问L列表中的元素
L = [2, 3, 5, 7]
for x in L:
print(x) # 2 3 5 6
# 以下用迭代器来访问L列表中的元素
L = [2, 3, 5, 7]
it = iter(L) # 先拿到迭代器用iter绑定
while True:
x = next(it) # 获取一个数据并绑定到x
print(x) # 2 3 5 71
2
3
4
5
6
7
8
9
10
生成器
定义
生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例)。
生成器有两种:生成器函数,生成器表达式。
生成器函数
含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象。
yield 语句:
语法:
yield 表达式
说明:
yield 用于 def 函数中,目的是将此函数作用生成器函数使用
yield 用来生成数据,供迭代器和next(it) 函数使用1
2
def myyield():
print("即将生成2")
yield 2
print("即将生成3")
yield 3
print("即将生成5")
yield 5
print("即将生成7")
yield 7
print("生成器生成结束")
gen = myyield()
it = iter(gen)
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # 5
print(next(it)) # 7
print(next(it)) # StopIteration1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1)写一个生成器函数 myeven(start, stop) 用来生成 start开始到stop结束(不包含stop)的偶数。
def myeven(start, stop):
while start < stop:
if start % 2 == 0:
yield start
start += 1
for x in myeven(1, 10):
print(x) # 2 4 6 8
L = [x ** 2 for x in myeven(2, 20)]
print(L)1
2
3
4
5
6
7
8
9
10
11
12
2)写一个生成器函数myfactorial(n)此函数用来生成n个从1开始的阶乘。
def myfactorial(n):
s = 1 # 用来保存阶乘
for x in range(1, n + 1):
s *= x
yield s
L = list(myfactorial(5)) # L = [1, 2, 6, 24, 120]
print(L)
print(sum(myfactorial(5)))1
2
3
4
5
6
7
8
9
10
11
函数zip用法
zip(iter1 [, iter2[…]]) 返回一个zip对象,此对象用于生成元组,此元组的每个数据来源于参数中的可迭代对象,当最小的可迭代对象不再提供数据时迭代结束。
def myzip(iter1, iter2):
it1 = iter(iter1) # 拿到两个对象的迭代器
it2 = iter(iter2)
while True:
try:
t = (next(it1), next(it2)) # StopIteration
yield t
except StopIteration:
break
numbers = [10086, 10000, 10010, 95588]
names = ['中国移动', '中国电信', '中国联通']
for t in myzip(numbers, names):
print(t)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
生命的意义不在于马到成功,而在于不断求索。