Python - 使用一个生成器在多个消费者内消耗

2024-10-03 00:22:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个发电机供不同的消费者使用。后者可以从生成器中获取不同的项,因此我不能只使用一个大for循环来处理所有项。我想要的是完全消耗发电机。怎么能做到呢?在

# -*- coding: utf-8 -*-
MEALS = ['Oysters', 'Consommé', 'Lamb', 'Rice', 'Sirloin','Banana', 'Pastry']

def server():
    for n in MEALS:
        yield n

def client(course, take):
    meal = []
    for _ in range(take):
        some_meal = next(course)
        meal.append(some_meal)
    return meal

if __name__ == '__main__':
    #print("Available meals: ", list(MEALS))
    course = server()
    try:
        while True:
            meal = client(course, 3)
            print("First client: ", meal)
            meal = client(course, 2)
            print("Second client: ", meal)
    except StopIteration:
        pass

电流输出:

^{pr2}$

但是甜点在哪里??在

预期产量:

First client:  ['Oysters', 'Consommé', 'Lamb']
Second client:  ['Rice', 'Sirloin']
First client:  ['Banana', 'Pastry']

更新下面接受的解决方案在返回的列表中添加了测试,这是可以接受的,只是我过度简化了示例代码(在client中可能有许多next语句)。我现在需要的是一种在第一个StopIteration出现时立即从client函数返回的方法。所以我添加了一个关于the best way to exit a function upon hitting the first StopIteration的后续问题。在


Tags: clientfor发电机firstbananaprintricecourse
1条回答
网友
1楼 · 发布于 2024-10-03 00:22:49

while循环的第二次迭代中,server生成器只需要再生成2个项目,client()函数将在尝试获取3个元素时触发StopIteration异常。在

您需要在client()函数中处理StopIteration

def client(course, take):
    meal = []
    for _ in range(take):
        try:
            some_meal = next(course)
            meal.append(some_meal)
        except StopIteration:
            pass
    return meal

既然客户机将处理StopIteration,那么您必须以不同的方式处理while循环;如果client()没有返回元素,server必须为空:

^{pr2}$

这里缺少了Python标准库中的一些技巧。您可以使用iter()重新实现您的server

def server():
    return iter(MEALS)

您可以使用^{}来处理您的客户:

from itertools import islice

def client(course, take):
    return list(islice(course, take))

相关问题 更多 >