Python异步编程02--yield用法

一、介绍

 1.协程: 微线程,是一种用户态轻量级线程
  如图:在执行A函数的时候,可以随时中断,去执行B函数,然后终端继续执行A函数(可以自动切换)

协程



 2.\color{#ea4335}{yield}:本身就是一种在单线程下可以保存任务运行状态的方法,它是代码级控制的,更轻量级。

二、使用方法

  • 生成器
    生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
# -*- coding:utf-8 -*-

def func1():
    for i in range(10):
        # 返回一个生成器对象
        yield i


if __name__ == '__main__':
    f = func1()
    print(next(f))
    print(next(f))

1-1


  • yield from用法:主要设计用来向子生成器委派操作任务
# -*- coding:utf-8 -*-

def func1():
    for i in range(10):
        # 返回一个生成器对象
        yield i


def func2(generator):
    # yield from必须在函数体中使用
    res = yield from generator
    print(res)


if __name__ == '__main__':
    fs = func1()
    # print(next(f))
    # print(next(f))
    # func2():生成器函数,封装生产器对象
    wrap_g = func2(fs)
    for w in wrap_g:
        print(w)

1-2


  • 协程:微线程,是一种用户态轻量级线程
# -*- coding:utf-8 -*-


def func3():
    for i in range(1, 11):
        print(f"我是客服{i}号")
        yield


def func4():
    # 由于func3()返回的是一个生成器对象,所以用一个变量接收一下
    g = func3()
    next(g)
    for i in range(1, 10):
        print(f"我的工{i}号")
        next(g)


if __name__ == '__main__':
    func4()

1-3部分图


二、yield生产者消费者模式:

# -*- coding:utf-8 -*-
from time import sleep


def customer():
    while True:
        sleep(1)
        # 接收生产者的消息,并向消费者发送
        n = yield
        print(f"生产{n}产品")
        yield


def producer():
    g = customer()
    next(g)
    for i in range(1, 10):
        sleep(1)
        # 向消费者发送值
        g.send(i)
        print(f"消费{i}产品")
        next(g)


if __name__ == '__main__':
    producer()

生产者、消费者模式


二、yield源码解读:

typedef struct _frame {
    /* 变长对象 (运行时大小不确定) */
    PyObject_VAR_HEAD
    /* 执行环境链上的前一个frame,很多个PyFrameObject连接起来形成执行环境链表 or Null  */
    struct _frame *f_back;
    /* PyCodeObject 对象,这个frame就是这个PyCodeObject对象的上下文环境 */
    PyCodeObject *f_code;
    /* builtin名字空间 */
    PyObject *f_builtins;
    /* global名字空间 */
    PyObject *f_globals;
    /* local名字空间 */
    PyObject *f_locals;
    /* "运行时栈"的栈底位置 */
    PyObject **f_valuestack;
    /* "运行时栈"的栈顶位置 */
    PyObject **f_stacktop;
    /* 计数 */
    PyObject *f_trace;

    /* 处理帧中引发了异常 异常类型,异常值,异常状态 */
    PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
    /* 初始化异常处理的状态 */
    PyThreadState *f_tstate;
    /* 上一条字节码指令在f_code中的偏移位置 */
    int f_lasti;
    /* 当前字节码对应的源代码行 */
    int f_lineno;
    /* 捕捉异常 */
    int f_iblock;       /* index in f_blockstack */
    /* f_iblock在调用PyFrame_New时被初始化为0 */
    PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
    /* 动态内存、维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间 */
    PyObject *f_localsplus[1];
} PyFrameObject;



\color{#ea4335}{要想有所成就,必须克服天性,提高自己的耐心水平和自己延迟满足的能力。 ---->箴言}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容