在 while True 循环中调用函数

Calling a function in a while True loop

背景 - 我有一个 .py 脚本,它对 API 进行 GET 调用,将响应保存为 .json 文件,在将 api_response 作为变量保存和返回之前,用于 def unpack_response 函数,该函数对 API 返回的数据

执行各种操作

问题 - 由于 API 不可靠且经常超时,我在 def unpack_response(): 中添加了 while True: 语句,目的是循环一段代码。重要的是,此函数的第一行调用了一个调用 API(api_response = response_writer()) 的函数,该函数提供了 api_response。自从实施 while True: 语句后,我的代码出现了以下错误 -

返回错误(自实施while True):

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-8-a3f8a13befee> in <module>
     36     print("---------------------------\n","EXCEPTION REPORT:", excep_row_count, "rows", "\n---------------------------")
     37 
---> 38 xlsx_writer()

<ipython-input-8-a3f8a13befee> in xlsx_writer()
      1 # Function that writes Exceptions Report and API Response as a consolidated .xlsx file.
      2 def xlsx_writer():
----> 3     df_raw, exceptions_df = ownership_qc()
      4 
      5 #   Creating and defining filename for exceptions report

<ipython-input-7-3c1d5b73cc07> in ownership_qc()
      3 
      4 #   Setting QC Columns
----> 5     df = unpack_response()
      6 
      7 #   Making a copy of df (normalized API response) to be written by def_xlsx_writer() function to same .xslsx as exceptions_df

<ipython-input-6-8c186a2a5f7a> in unpack_response()
     15 
     16 #   Holding Account refered to as 'name' in JSON file, and not found in column list. Therefore requires manual renaming.
---> 17     df.rename(columns={'name': 'Holding Account'}, inplace=True)
     18 
     19 #   Reordering columns, to match View in Addepar

UnboundLocalError: local variable 'df' referenced before assignment

实现while True:语句之前的功能:(这很有效)-

def unpack_response():  
    api_response = response_writer()
    df = pd.json_normalize(api_response['data']['attributes']['total']['children'])
    df.drop(columns=['grouping', 'entity_id'], inplace=True)
    df.columns = df.columns.str.replace(r'columns.', '')
    column_name_mapper = {column['key']: column['display_name'] for column in api_response['meta']['columns']}
    df.rename(columns=column_name_mapper, inplace=True)

    df.rename(columns={'name': 'Holding Account'}, inplace=True)

    column_names = ["Holding Account", "Entity ID", "Holding Account Number", "Adjusted Value (USD)", "% Ownership", "Model Type", "Valuation (USD)", "JP Custodian",
                   "Top Level Owner", "Top Level Legal Entity", "Direct Owner", "Online Status", "Financial Service", "Placeholder or Fee Basis", 
                    "Account Close Date", "Ownership Audit Note"]
    df = df.reindex(columns=column_names)

    index = df.index
    number_of_rows = len(index)
    print("---------------------------------------------\n",
          "DATAFRAME CONSTRUCTED SUCCESSFULLY:", number_of_rows, "rows", "\n---------------------------------------------")
    
    return df

执行while True:语句后的函数:(returns以上错误)-

def unpack_response():
    while True:
        try:    
            api_response = response_writer()
            df = pd.json_normalize(api_response['data']['attributes']['total']['children'])
            df.drop(columns=['grouping', 'entity_id'], inplace=True)
            df.columns = df.columns.str.replace(r'columns.', '')
            column_name_mapper = {column['key']: column['display_name'] for column in api_response['meta']['columns']}
            df.rename(columns=column_name_mapper, inplace=True)
        except KeyError:
                    print("-----------------------------------\n","API TIMEOUT ERROR: TRYING AGAIN...", "\n-----------------------------------\n")
        break

    df.rename(columns={'name': 'Holding Account'}, inplace=True)

    column_names = ["Holding Account", "Entity ID", "Holding Account Number", "Adjusted Value (USD)", "% Ownership", "Model Type", "Valuation (USD)", "JP Custodian",
                   "Top Level Owner", "Top Level Legal Entity", "Direct Owner", "Online Status", "Financial Service", "Placeholder or Fee Basis", 
                    "Account Close Date", "Ownership Audit Note"]
    df = df.reindex(columns=column_names)

    index = df.index
    number_of_rows = len(index)
    print("---------------------------------------------\n",
          "DATAFRAME CONSTRUCTED SUCCESSFULLY:", number_of_rows, "rows", "\n---------------------------------------------")
    
    return df

问题 - 这是我第一次实现 while True 语句,我想知道我是否做错了?如果有人可以帮助识别并教我如何正确实施

你最终打破了 while true 循环,无论是否抛出异常都使用“break”。然后代码在以下行崩溃,因为未声明“df”:

df.rename(columns={'name': 'Holding Account'}, inplace=True)

如果相应地更改 while true 循环的中断,它应该继续运行直到成功:

def unpack_response():
while True:
    try:    
        api_response = response_writer()
        df = pd.json_normalize(api_response['data']['attributes']['total']['children'])
        df.drop(columns=['grouping', 'entity_id'], inplace=True)
        df.columns = df.columns.str.replace(r'columns.', '')
        column_name_mapper = {column['key']: column['display_name'] for column in api_response['meta']['columns']}
        df.rename(columns=column_name_mapper, inplace=True)
        break
    except KeyError:
        print("-----------------------------------\n","API TIMEOUT ERROR: TRYING AGAIN...", "\n-----------------------------------\n")
    
df.rename(columns={'name': 'Holding Account'}, inplace=True)

column_names = ["Holding Account", "Entity ID", "Holding Account Number", "Adjusted Value (USD)", "% Ownership", "Model Type", "Valuation (USD)", "JP Custodian",
               "Top Level Owner", "Top Level Legal Entity", "Direct Owner", "Online Status", "Financial Service", "Placeholder or Fee Basis", 
                "Account Close Date", "Ownership Audit Note"]
df = df.reindex(columns=column_names)

index = df.index
number_of_rows = len(index)
print("---------------------------------------------\n",
      "DATAFRAME CONSTRUCTED SUCCESSFULLY:", number_of_rows, "rows", "\n---------------------------------------------")

return df

您真的应该考虑添加一个 time.sleep(10) 以便延迟重试。