且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

python莫名其妙的yield, yield from, yield.send

更新时间:2022-08-16 17:21:13

练了几行代码,

慢慢找感觉。

TASK,多线程,异步,很多地方都用到的呢。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
from contextlib import contextmanager
from concurrent.futures import ThreadPoolExecutor

class Task:
    def __init__(self, gen):
        self._gen = gen

    def step(self, value=None, exc=None):
        try:
            if exc:
                fut = self._gen.throw(exc)
            else:
                fut = self._gen.send(value)
            fut.add_done_callback(self._wakeup)
        except StopIteration as exc:
            pass

    def _wakeup(self, fut):
        try:
            result = fut.result()
            self.step(result, None)
        except Exception as exc:
            self.step(None, exc)


def func(x, y):
    'Some function. Nothing too interesting'
    import time
    time.sleep(2)
    return x + y

def do_func(x, y):
    try:
        result = yield pool.submit(func, x, y)
        print("Got: ", result)
    except Exception as e:
        print("Failed: ", repr(e))

def do_many(n):
    while n > 0:
        result = yield pool.submit(func, n, n)
        print("Got: ", result)
        n -= 1

def after(delay, gen):
    yield from pool.submit(time.sleep, delay)
    yield from gen
    print("GOOOOT: ", result)
    '''
    result = None
    try:
        while True:
            f = gen.send(result)
            result = yield f
        # print("GOOOT: ", result)
    except StopIteration:
        pass
    print("GOOOT: ", result)
    '''

pool = ThreadPoolExecutor(max_workers=8)
# fut = pool.submit(func, 2, 3)
# r = fut.result()
# print('Got:', r)

t = Task(do_func(2, 3))
t.step()
t = Task(do_func(2, "Hello"))
t.step()
Task(after(3, do_func(2, 3))).step()
t = Task(do_many(10))
t.step()




def countdown(n):
    print ("Counting down from ", n)
    while n > 0:
        yield n
        n -= 1

def coroutine(func):
    def start(*args, **kwargs):
        cr = func(*args, **kwargs)
        next(cr)
        return cr
    return start

@coroutine
def grep(pattern):
    print ("Looking for %s " % pattern)
    try:
        while True:
            line = (yield)
            if pattern in line:
                print (line,)
    except GeneratorExit:
        print ("Going away. Goodbye.")

g = grep("python")
g.send("Yeah, but no, but yeah")
g.send("python generatores rock!")
g.close()

def receiver():
    while True:
        item = yield
        print("Got ", item)

recv = receiver()
next(recv)
recv.send("hello")
recv.send("world")

def chain(x, y):
    yield from x
    yield from y

a = [1, 2, 3]
b = [4, 5, 6]
for x in chain(a, b):
    print(x, end=" ")