python递归装饰器

时间:2019-09-02 11:58:31

标签: python recursion decorator

我有一个函数,可以从API调用返回字典列表。 API每个请求最多可返回100条记录。记录存储在页面中,每页包含100条记录。

def call_api(page):
    return list_of_records

我需要的是一个装饰器,该装饰器每次在返回带有页参数= + 1的100条记录时都可以重新运行此函数。

类似:

if len(list_of_records) == 100:
   call_api(page +=1)

最终输出应为包含所有记录的单个列表

1 个答案:

答案 0 :(得分:2)

定义一个可以递归调用一个函数的装饰器当然是可能的。

在您的情况下,这样的装饰器可能是这样:

import functools

def with_pages(func):
    @functools.wraps(func)

    def wrapper(page):
        list_of_records = []
        partial_list = func(page)
        list_of_records.extend(partial_list)
        while len(partial_list) == 100:  # there is probably a better condition to check if you are at the last page (e.g. next_page URI in api reply)
            page += 1
            partial_list = func(page)
            list_of_records.extend(partial_list)
        return list_of_records
    return wrapper

@with_pages
def call_api(page):
    # api interaction creating list_of_records_on_a_page
    return list_of_records_on_a_page

或者,您可以调整call_api以便可以递归调用。

类似的东西:

def call_api(page, list_of_records=[]):
    partial_list = ... # the records you get from the api
    list_of_records.extend(partial_list)
    # often api provide the url for the next page or some more reliable info
    # about whether or not you are on the last page, i.e. testing for the length
    # of the reply is probably not the best strategy
    if len(partial_list) == 100:
        # time.sleep(0.2)  # just to not end up with to many requests in a short period of time
        call_api(page + 1, list_of_records)
    return list_of_records

只需调用call_api(1)就可以获取所有页面。