如何在Flask中使用Python生成器

3

每次请求flask API时,我希望获得递增的值。但是由于series()对象一遍又一遍地被创建,所以我总是得到相同的值。

我已经制作了flask API和生成器函数。

最初的回答:


    @app.route('/eRxBot/Increment', methods=['POST','GET'])
    def Gen():
       gen =series()
       val =str(next(gen))
       print(val)
       res = Response(val)
       return res


    def series():
        for i in range(1,999):
            yield i

输出:

1 2 3

每次 API 调用都会递增。

润色后的翻译结果如上所示。

看起来你不知道什么是RESTful,看看这个链接:https://dev59.com/a3RB5IYBdhLWcg3wSVcI - Waket Zheng
如果你想在每次API调用中递增,那是不可能的,因为状态不会跨调用保存。如果你想实现类似的功能,也许可以使用会话(session)之类的东西,但从REST原则的角度来看,这似乎是一个非常糟糕的做法。你实际上想要实现什么? - Shuvojit
1个回答

4
您所看到的问题是每个HTTP请求都创建了一个新的系列生成器实例。将生成器的实例移到视图函数之外,它将随着每个请求递增。
但是状态不会在应用程序重新启动或在多个进程之间同步存储,这需要一个后备数据存储。
以下是工作版本和使用Redis来支持值生成而不是本地生成器的示例。 编辑:对于基于生成器的示例,现在每天重置系列。
from flask import Flask, Response
from flask_redis import FlaskRedis
import datetime

app = Flask(__name__)
redis_store = FlaskRedis(app)
redis_key = "my_incr"


def series():
    for i in range(1, 999):
        yield i


def make_get_or_rotate_series():
    today = datetime.date.today()
    current_series = series()

    def get_or_rotate_series(current_day=None):
        nonlocal today, current_series
        current_day = current_day if current_day else datetime.date.today()

        if today != current_day:
            today = current_day
            current_series = series()

        return current_series
    return get_or_rotate_series


get_series = make_get_or_rotate_series()


@app.route('/eRxBot/Increment', methods=['POST', 'GET'])
def gen():
    val = str(next(get_series()))
    print(val)
    res = Response(val)
    return res


@app.route('/eRxBot/Increment-Redis', methods=['POST', 'GET'])
def gen_redis():
    val = redis_store.incr(redis_key)
    res = Response(str(val))
    return res


if __name__ == "__main__":
    # tests
    test_get_series = make_get_or_rotate_series()
    assert next(test_get_series()) == 1
    assert next(test_get_series()) == 2
    tomorrow = datetime.date.today() + datetime.timedelta(days=1)
    assert next(test_get_series(tomorrow)) == 1
    assert next(test_get_series(tomorrow)) == 2

    app.run()



谢谢Steve McCartney,它运行良好。 - Praveen K M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接