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

相关推荐
IvanCodes4 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化
开发语言·python
Patrick在香港5 小时前
Claude 工具调用返回空:8 次失败里只有 1 次状态码不对,其余全带 200
爬虫·python·api·claude·香港
Web3&Basketball5 小时前
CRM Agent 后训练实战:3 倍更少错误
python·架构·大模型·agent·推理
aramae5 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
AIFQuant6 小时前
ETF行情API接入踩坑记:从报错到跑通的七个问题
python·金融·区块链·etf·基金
GPU实战笔记7 小时前
云端 Python 开发:JupyterLab 还是 VS Code Remote-SSH?
python·vs code·jupyterlab·remote-ssh·远程开发
狗狗狗狗狗乐啊8 小时前
搭一个 AI 对话工作台 AChat:从 0 到可用的完整记录(一)
python·react.js·ai编程
qq_2518364578 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
白猫不黑8 小时前
Python实现简易Web弱口令爆破与防护方案
python·web安全·计算机·网络安全·黑客·信息安全·渗透测试
郑州光合科技余经理9 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程