【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.

相关推荐
idingzhi8 分钟前
A股量化策略日报(2026年05月22日)
android·开发语言·python·kotlin
song50115 分钟前
多卡训练加速:HCCL 集合通信实战
分布式·python·flutter·ci/cd·分类
江上清风山间明月34 分钟前
如何将python开发的window应用打包成exe
开发语言·python·exe·打包
知识分享小能手36 分钟前
Flask入门学习教程,从入门到精通, Flask模板 — 完整知识点与案例代码 (2)
python·学习·flask
SXJR40 分钟前
Java中的Cross-Encoder模型解决方案
java·开发语言
不懒不懒40 分钟前
基于 Flask —— 异步任务处理接口服务
后端·python·flask
happybasic44 分钟前
Python库升级标准流程~
linux·前端·python
彦为君1 小时前
JavaSE-11-BIO/NIO/AIO(多人聊天室)
java·开发语言·python·ai·nio
恣艺1 小时前
Python 实用工具与机器学习入门:Rich + Tqdm + Faker + Schedule + Scikit-learn
python·机器学习·scikit-learn
为何创造硅基生物1 小时前
C 语言 typedef 结构体私有化
c语言·开发语言·算法