异常处理后返回的DataFrame为NoneType的问题求助
问题:捕获FileNotFoundError后递归调用函数返回NoneType导致AttributeError
在读取Excel文件时,捕获FileNotFoundError并打印错误信息后递归调用read_wb(),但第二次输入正确文件名找到文件时,返回的df仍为NoneType,后续函数使用该df时触发AttributeError: 'NoneType' object has no attribute 'loc'。
相关代码
原read_wb函数
def read_wb(): try: wb_name = input("What is the name of your workbook (add .xlsx): ") df = pd.read_excel(wb_name) return df except FileNotFoundError: print("Ooops... It looks like this file is spelled wrong or it's not in the same folder of the script. Try again.") read_wb()
报错调用片段
def main(): df = read_wb() --> df = modify_df(df) df = return_ws(df) repeat = input("Do want to run another file ('y' or 'n'): ").lower()
完整报错栈
AttributeError Traceback (most recent call last) c:\Users\vn54jdq\Downloads\WFS Review Folders\Hams Filter Project.ipynb Cell 20 in <cell line: 146>() 145 main() 146 if __name__ == "__main__": --> 147 main() c:\Users\vn54jdq\Downloads\WFS Review Folders\Hams Filter Project.ipynb Cell 20 in main() 139 def main(): 140 df = read_wb() --> 141 df = modify_df(df) 142 df = return_ws(df) 143 repeat = input("Do want to run another file ('y' or 'n'): ").lower() c:\Users\vn54jdq\Downloads\WFS Review Folders\Hams Filter Project.ipynb Cell 20 in modify_df(df) 18 tic = time.perf_counter() 19 ## This first part of the script goes through the list product_cat and product_cat_type. 20 ## If found, then it will mark a 'n' in the Chemical (Y/N) columns so it can be counted as an exclusion. 21 ## Then it searches for product types that are in the key flags that we are searching for like chemical...etc ---> 23 df.loc[df[df['Product Category'].str.contains(r'(?:\b(?=\w)|(?!\w))(?:{})(?:\b(?<=\w)|(?<!\w))'.format('|'.join(sorted(map(re.escape, product_cat), key=len, reverse=True))), case=False, regex=True).fillna(False)].index, "Chemical (Y/N)"] = 'n' 24 df.loc[df[df['Product Type'].str.contains(r'(?:\b(?=\w)|(?!\w))(?:{})(?:\b(?<=\w)|(?<!\w))'.format('|'.join(sorted(map(re.escape, values_flattened), key=len, reverse=True))), case=False, regex=True).fillna(False)].index, "Chemical (Y/N)"] = 'n' 25 df.loc[df[df['Product Type'].str.contains(r'(?:\b(?=\w)|(?!\w))(?:{})(?:\b(?<=\w)|(?<!\w))'.format('|'.join(sorted(map(re.escape, chem_values_flattened), key=len, reverse=True))), case=False, regex=True).fillna(False)].index, "Chemical (Y/N)"] = 'y' AttributeError: 'NoneType' object has no attribute 'loc'
问题原因
异常处理块中递归调用read_wb()时,没有返回该递归调用的结果。第一次调用read_wb()触发异常后进入递归,内层的read_wb()成功读取文件并返回df,但外层的read_wb()函数没有将这个结果返回,最终导致外层函数默认返回None。
解决方案
方案1:修复递归调用的返回值
修改异常块,返回递归调用的read_wb()结果:
def read_wb(): try: wb_name = input("What is the name of your workbook (add .xlsx): ") df = pd.read_excel(wb_name) return df except FileNotFoundError: print("Ooops... It looks like this file is spelled wrong or it's not in the same folder of the script. Try again.") return read_wb() # 新增return,返回递归调用的结果
方案2:用循环替代递归(更推荐)
递归多次重试可能导致栈溢出,改用循环实现更稳健:
def read_wb(): while True: try: wb_name = input("What is the name of your workbook (add .xlsx): ") df = pd.read_excel(wb_name) return df except FileNotFoundError: print("Ooops... It looks like this file is spelled wrong or it's not in the same folder of the script. Try again.")
验证效果
修改后,无论第一次输入错误多少次,只要最后输入正确文件名,函数都会正确返回读取到的DataFrame,后续modify_df(df)调用不会再触发AttributeError。
内容的提问来源于stack exchange,提问作者Kevin Rodgers Jr.
相关产品推荐
相关产品推荐

