【python 生成器 面试必备】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 2

这篇文章要解决的问题:How to Pass Value to Generators Using the "yield" Expression in Python

ref:https://python.plainenglish.io/yield-python-part-ii-e93abb619a16

1.如何传值

yield 是一个表达式!!!!

yield is an expression! It is used just like an expression would:

received = yield 'hello'

In this case value of received is hello .

received = yield

Here, the value of received is None .

However, it's been suggested to use the expression form sparingly also because of confusion.

但是也有人建议少用,因为容易引起混淆!

2.yield 生成器的几种状态

···python

from inspect import getgeneratorstate

复制代码
def gen_echo():
    while True:
        received = yield
        print(f'Inside method: {getgeneratorstate(echo)}')
        print(f'You said: {received}')


echo = gen_echo()
print(f'After generator creation: {getgeneratorstate(echo)}')
print(f'First call value to generator: {next(echo)}')
print(f'After first call to generator: {getgeneratorstate(echo)}')

# sending value to generator
echo.send('hello')

print(f'After sending the value: {getgeneratorstate(echo)}')

···

bash 复制代码
C:\Users\HP\.conda\envs\torch1.8\python.exe D:/code/python_project/01-coroutine-py-mooc/8/demo_ccc.py
After generator creation: GEN_CREATED
First call value to generator: None
After first call to generator: GEN_SUSPENDED
Inside method: GEN_RUNNING
You said: hello
After sending the value: GEN_SUSPENDED

3.原理图

其实就是线程【用户级线程=也叫协程】的状态转换图!!!

3.协程练习

3.1 原始方式

python 复制代码
def running_averager():
    total = 0
    count = 0
    running_average = None
    while True:
        value = yield running_average
        total += value
        count += 1
        running_average = total/count

averager = running_averager() # generator creation
next(averager) # priming
print(averager.send(10))
print(averager.send(20))
print(averager.send(30))

3.2 闭包【装饰器】方式

3.1相同的功能代码再用闭包的方式实现一遍,After priming, the generator is on suspend state, after which we can send data to a generator and get running_average.

Since we have to do that extra step of next() to generator, why not have it automated. We have a decorator to do that.

python 复制代码
def prime(generator_fun):
    '''
    Method to prime generator function
    '''
    generator = generator_fun()
    next(generator)
    return generator

def running_averager():
    '''
    calculates average of values sent
    '''
    total = 0
    count = 0
    running_average = None
    while True:
        value = yield running_average
        total += value
        count += 1
        running_average = total/count

iterable = [10, 11, 12, 13, 14, 15]
averager = prime(running_averager) # decorating

for value in iterable:
    running_average = averager.send(value)
    print(running_average)

输出:

复制代码
10.0
10.5
11.0
11.5
12.0
12.5

4.总结

In summary, yield is an expression too and we can send value to a generator when it is in suspend state. The first suspend state is achieved by priming the generator.

相关推荐
Boilermaker19921 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
沈浩(种子思维作者)1 小时前
真的能精准医疗吗?癌症能提前发现吗?
人工智能·python·网络安全·健康医疗·量子计算
MM_MS2 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
꧁Q༒ོγ꧂2 小时前
LaTeX 语法入门指南
开发语言·latex
njsgcs2 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_992 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
io_T_T2 小时前
迭代器 iteration、iter 与 多线程 concurrent 交叉实践(详细)
python
古城小栈2 小时前
Rust 迭代器产出的引用层数——分水岭
开发语言·rust
华研前沿标杆游学2 小时前
2026年走进洛阳格力工厂参观游学
python
Carl_奕然3 小时前
【数据挖掘】数据挖掘必会技能之:A/B测试
人工智能·python·数据挖掘·数据分析