defconsumer():
r =''whileTrue:
n =yield r
ifnot n:returnprint(f'[CONSUMER] Consuming get params.. ({n})')if n ==3:
r ='500 Error'else:
r ='200 OK'defproduce(c):
c.send(None)# 启动生成器
n =0while n <5:
n = n +1print(f'[PRODUCER] Producing with params.. ({n})')
r = c.send(n)# 一旦n有值,则切换到consumer执行print(f'[PRODUCER] Consumer return : [{r}]')ifnot r.startswith('200'):print("消费者返回服务异常,则结束生产,并关闭消费者")
c.close()# 关闭生成器break
consume = consumer()
produce(consume)# [PRODUCER] Producing with params.. (1)# [CONSUMER] Consuming get params.. (1)# [PRODUCER] Consumer return : [200 OK]# [PRODUCER] Producing with params.. (2)# [CONSUMER] Consuming get params.. (2)# [PRODUCER] Consumer return : [200 OK]# [PRODUCER] Producing with params.. (3)# [CONSUMER] Consuming get params.. (3)# [PRODUCER] Consumer return : [500 Error]# 消费者返回服务异常,则结束生产,并关闭消费者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
yield from iterable 语法,基本作用为:
返回一个生成器对象,提供一个“数据传输的管道”
,yield from iterable 是 for item in iterable: yield item的缩写;并且内部帮我们实现了很多异常处理,简化了编码复杂度。
yield 无法获取生成器return的返回值:
defmy_generator(n, end_case):for i inrange(n):if i == end_case:returnf'当 i==`{i}`时,中断程序。'else:yield i
g = my_generator(5,2)# 调用for _i in g:# for循环不会显式触发异常,故而无法获取到return的值print(_i)# 输出:# 0# 1
defmy_generator2(n, end_case):for i inrange(n):if i == end_case:returnf'当 i==`{i}`时,中断程序。'else:yield i
g = my_generator2(5,2)# 调用try:print(next(g))# 0print(next(g))# 1print(next(g))# 此处要触发end_case了except StopIteration as exc:print(exc.value)# 当 i==`2`时,中断程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
使用yield from 可以简化成:
defmy_generator3(n, end_case):for i inrange(n):if i == end_case:returnf'当 i==`{i}`时,中断程序。'else:yield i
defwrap_my_generator(generator):# 将my_generator的返回值包装成一个生成器
result =yieldfrom generator
yield result
g = my_generator3(5,2)# 调用for _ in wrap_my_generator(g):print(_)# 输出:# 0# 1# 当 i==`2`时,中断程序。
from functools import wraps
defw1(func):@wraps(func)defwrapper(*args,**kwargs):print("这里是第一个校验")return func(*args,**kwargs)return wrapper
defw2(func):@wraps(func)defwrapper(*args,**kwargs):print("这里是第二个校验")return func(*args,**kwargs)return wrapper
defw3(func):defwrapper(*args,**kwargs):print("这里是第三个校验")return func(*args,**kwargs)return wrapper
@w2# 这里其实是w2(w1(f1))@w1# 这里是w1(f1)deff1():print(f"i`m f1, at {f1}")@w3deff2():print(f"i`m f2, at {f2}")# ====================== 实例化阶段 =====================
f1()# 这里是第二个校验# 这里是第一个校验# i`m f1, at <function f1 at 0x7febc52f5e50>
f2()# 这里是第三个校验# i`m f2, at <function w3.<locals>.inner at 0x7febc52f5f70>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
有同学可能要好奇 为什么f1对象打印的是“<function f1 at 0x7febc52f5e50>”,f2对象打印的是“<function w3..wrapper at 0x7febc52f5f70>”(也就是步骤2.5造成的,赋的值是wrapper对象),这就跟w1和w2 内部wrapper使用的wraps装饰器有关系了。
wraps的作用是:被修饰的函数(也就是里面的func)的一些属性值赋值给修饰器函数(wrapper)包括元信息和“函数对象”等。
同时装饰器也可以接受参数:
defdecorator_get_function_duration(enable):"""
:param enable: 是否需要统计函数执行耗时
:return:
"""print("this is decorator_get_function_duration")definner(func):print('this is inner in decorator_get_function_duration')@wraps(func)defwrapper(*args,**kwargs):print('this is a wrapper in decorator_get_function_duration.inner')if enable:
start = time.time()print(f"函数执行前:{start}")
result = func(*args,**kwargs)print('[%s]`s enable was %s it`s duration : %.3f s '%(func.__name__, enable, time.time()- start))else:
result = func(*args,**kwargs)return result
return wrapper
return inner
defdecorator_1(func):print('this is decorator_1')@wraps(func)defwrapper(*args,**kwargs):print('this is a wrapper in decorator_1')return func(*args,**kwargs)return wrapper
defdecorator_2(func):print('this is decorator_2')@wraps(func)defwrapper(*args,**kwargs):print('this is a wrapper in decorator_2')return func(*args,**kwargs)return wrapper
@decorator_1# 此处相当:decorator_1(decorator_2(decorator_get_function_duration(enable=True)(fun)))@decorator_2# = decorator_2(decorator_get_function_duration(enable=True)(fun))@decorator_get_function_duration(enable=True)# = decorator_get_function_duration(enable=True)(fun)deffun():
time.sleep(2)print("fun 执行完了~")
fun()# ======== enable=False ============"""
this is decorator_get_function_duration
this is inner in decorator_get_function_duration
this is decorator_2
this is decorator_1
this is a wrapper in decorator_1
this is a wrapper in decorator_2
this is a wrapper in decorator_get_function_duration.inner
fun 执行完了~
"""# ======== enable=True ============"""
this is decorator_get_function_duration
this is inner in decorator_get_function_duration
this is decorator_2
this is decorator_1
this is a wrapper in decorator_1
this is a wrapper in decorator_2
this is a wrapper in decorator_get_function_duration.inner
函数执行前:1634635708.648994
fun 执行完了~
[fun]`s enable was True it`s duration : 2.002 s
"""