Python递归函数在elif/else块返回None的原因排查求助
咱们来一步步拆解你遇到的问题核心:递归调用时没有正确传递返回值,再加上条件分支的逻辑设计,导致上层函数拿不到最终的正确结果。
1. 递归调用的返回值丢失问题
先看你这段递归调用的代码:
if len(items) < total_results: params['start_index'] = len(items) self.fetch_company_officers(company_number=company_number, items=items, **params)
当最内层的递归满足len(items) == total_results的条件,返回了组装好的r时,这个返回值只会回到上一层递归的调用位置,但你没有把这个返回值再return出去。上层函数执行完递归调用后,没有后续的return语句,就会默认返回None,最终最外层的调用拿到的就是这个None。
2. elif分支的逻辑陷阱
你原代码用了elif len(items) == total_results,这意味着只有当len(items) < total_results不成立时,才会进入这个返回分支。但items是可变列表,递归调用里的items.extend()会直接修改上层函数里的items。当递归完成后,items的长度已经等于total_results了,但此时程序已经走过了if分支,不会再进入elif分支,所以上层函数没有触发return,只能返回None。
而当你把elif改成if后,不管前面的if分支有没有执行,都会检查这个if条件。递归调用完成后,items长度达标,就会进入这个分支返回r,自然就能得到正确结果。
两种修复方案
方案一:传递递归返回值(更规范的递归写法)
修改递归调用的部分,把递归的返回值return出去,让每一层递归都把结果传递回上层:
if len(items) < total_results: params['start_index'] = len(items) # 关键:把递归的返回值return出去 return self.fetch_company_officers(company_number=company_number, items=items, **params) elif len(items) == total_results: r['items'] = items return r
这样最内层递归返回的r会一层一层传递回最外层调用,就能得到正确结果。
方案二:调整分支逻辑(简化版)
因为递归的目的就是把items补全到total_results的长度,所以递归完成后直接组装返回即可,不需要elif判断:
if len(items) < total_results: params['start_index'] = len(items) self.fetch_company_officers(company_number=company_number, items=items, **params) # 递归完成后,items长度肯定等于total_results了 r['items'] = items return r
这种写法更简洁,但要确保递归逻辑一定能把items补全到目标长度(比如接口返回的total_results是准确的)。
内容的提问来源于stack exchange,提问作者user9182913

