A little understanding of Python cooperation

Keywords: Python calculator

yield

def test():
    for i in 'abc':
        yield i
    for i in [1, 2, 3]:
        yield i


if __name__ == '__main__':
    gen = test()
    print(gen.send(None))
    print(gen.send(None))
    print(gen.send(None))
    print(gen.send(None))
    print(gen.send(None))
    print(gen.send(None))
    print(gen.send(None))
def test():
    for i in 'abc':
        yield i
    for i in [1, 2, 3]:
        yield i


if __name__ == '__main__':
    gen = test()
    for i in gen:
        print(i)

Use the for loop generator because the for loop can catch StopIteration exceptions.

yield from

The above code can also be implemented with yield from

def test():
    yield from 'abc'
    yield from [1, 2, 3]


if __name__ == '__main__':
    gen = test()
    for i in test():
        print(i)

What needs to be added after yield from is an iteratable object. It can be a normal iteratable object, an iterator, or even a generator.

Using yield from to implement real-time calculator

def average_gen():
    """
    //Child generator
    """
    average = 0
    total = 0
    count = 0
    while True:
        num = yield average
        if num is None:
            break
        count += 1
        total += num
        average = total / count
    return average, count, total


def proxy_gen():
    """
    //Delegation generator
    """
    while True:
        average, count, total = yield from average_gen()
        print(f'average value{average}, Calculation{count}second, The sum{total}')


def client():
    """
    //Call end
    """
    calc_average = proxy_gen()
    calc_average.send(None)
    # next(calc_average)
    # Pre activation process
    print(calc_average.send(10))
    print(calc_average.send(20))
    print(calc_average.send(30))
    calc_average.send(None)
    # Close association


if __name__ == '__main__':
    client()

In the delegation generator, when true can be replaced with a for loop. The size of the loop determines the number of times that the caller can call "average. Send (none) (the first pre activation is also included).

while True and for loops are used to catch StopIteration exceptions. You can see the first piece of code.

Example

def average_gen():
    """
    //Child generator
    """
    average = 0
    total = 0
    count = 0
    while True:
        num = yield average
        if num is None:
            break
        count += 1
        total += num
        average = total / count
    return average, count, total


def proxy_gen():
    """
    //Delegation generator
    """
    for i in range(2):
        average, count, total = yield from average_gen()
        print(f'average value{average}, Calculation{count}second, The sum{total}')


def client():
    """
    //Call end
    """
    calc_average = proxy_gen()
    calc_average.send(None)
    # next(calc_average)
    # Pre activation process
    print(calc_average.send(10))
    print(calc_average.send(20))
    print(calc_average.send(30))
    calc_average.send(None)
    # Close association
    print(calc_average.send(10))
    print(calc_average.send(20))
    print(calc_average.send(30))
    calc_average.send(None)


if __name__ == '__main__':
    client()

The example finally throws a StopIteration exception.

Because the for loop catches an exception in the second call and enters the last one. When the call for average.send (none), for cannot loop again and cannot handle the StopIteration exception, so it is thrown.

Posted by imtaqi on Sat, 30 Nov 2019 15:24:24 -0800