Python递归函数中使用for循环遍历类继承路径的问题
解决Python递归查找类所有继承路径的问题
类继承结构
首先明确给定的类继承关系:
class A: pass class B(A): pass class C(A): pass class F(A): pass class L(C,B): pass class D(B,F): pass class M(L,D): pass
我们需要输出的预期结果是[[M, L, C, A], [M, L, B, A], [M, D, B, A], [M, D, F, A]](打印类名更直观)。
错误原因分析
你遇到的几个问题根源如下:
- 仅返回单条路径:最初的递归函数在找到第一条有效路径后直接
return,没有遍历当前类的所有父类,也没有收集所有父类的递归结果。 - 仅返回最后一条路径:调整
return位置后,可能每次循环都覆盖了结果集合,或者最终只返回了最后一个父类的递归路径,没有合并所有父类的路径。 - yield类型错误:直接尝试将列表与生成器拼接(比如
[cls] + find_paths(base)),Python不允许列表和生成器直接相加,需要遍历生成器的元素再处理。
正确实现方式
方式1:返回列表的递归函数
这种方式通过递归收集所有路径,逻辑直观:
def find_inheritance_paths(cls): # 终止条件:当前类无父类(或仅继承自object),返回包含当前类的单元素列表 if not cls.__bases__ or cls.__bases__[0] is object: return [[cls]] all_paths = [] # 遍历当前类的每个直接父类 for base_cls in cls.__bases__: # 递归获取父类的所有继承路径 base_paths = find_inheritance_paths(base_cls) # 将当前类添加到每条父类路径的开头,并入总结果 for path in base_paths: all_paths.append([cls] + path) return all_paths # 测试调用,打印类名方便查看 for path in find_inheritance_paths(M): print([c.__name__ for c in path])
方式2:使用yield的生成器实现
如果不想一次性生成所有列表(处理大量类时更节省内存),可以用yield逐个生成路径:
def find_inheritance_paths_yield(cls): # 终止条件:直接生成包含当前类的单元素路径 if not cls.__bases__ or cls.__bases__[0] is object: yield [cls] return # 遍历每个父类,递归生成路径并处理 for base_cls in cls.__bases__: for path in find_inheritance_paths_yield(base_cls): yield [cls] + path # 测试调用 for path in find_inheritance_paths_yield(M): print([c.__name__ for c in path])
输出结果
两种方式都会输出预期的4条路径:
['M', 'L', 'C', 'A']['M', 'L', 'B', 'A']['M', 'D', 'B', 'A']['M', 'D', 'F', 'A']
内容的提问来源于stack exchange,提问作者jamie
相关产品推荐
相关产品推荐

