如何递归列出Python嵌套对象模型中任意深度的所有对象?
递归遍历嵌套行星数据结构的实现方法
这问题挺典型的,递归处理嵌套对象结构嘛,我给你写个实用的实现思路和代码,直接就能用。
完整实现代码
class Planet: def __init__(self, name): self.name = name self.continents = [] class Continent: def __init__(self, name): self.name = name self.countries = [] class Country: def __init__(self, name): self.name = name self.states = [] class State: def __init__(self, name): self.name = name self.cities = [] class City: def __init__(self, name): self.name = name def list_all_objects(obj, depth=0): # 生成缩进,让层级关系更直观 indent = " " * depth # 打印当前对象的类型和名称 print(f"{indent}{type(obj).__name__}: {obj.name}") # 根据对象类型匹配对应的子集合属性 child_collection = None if isinstance(obj, Planet): child_collection = obj.continents elif isinstance(obj, Continent): child_collection = obj.countries elif isinstance(obj, Country): child_collection = obj.states elif isinstance(obj, State): child_collection = obj.cities # 递归遍历所有子对象 if child_collection is not None: for child in child_collection: list_all_objects(child, depth + 1) # 测试示例 if __name__ == "__main__": # 构建一个嵌套结构的示例数据 earth = Planet("Earth") asia = Continent("Asia") china = Country("China") guangdong = State("Guangdong") guangzhou = City("Guangzhou") guangdong.cities.append(guangzhou) china.states.append(guangdong) asia.countries.append(china) earth.continents.append(asia) # 调用函数遍历所有对象 list_all_objects(earth)
代码逻辑说明
核心递归逻辑:
- 用
depth参数控制缩进,让不同层级的对象输出有明显区分,可读性拉满。 - 先打印当前对象的类名和名称,明确每个节点的身份。
- 通过
isinstance判断对象类型,找到对应的子对象集合(比如行星的continents、大陆的countries)。 - 遍历子集合里的每个对象,递归调用函数并增加层级,实现深度遍历。
- 用
测试输出效果:
运行代码后会得到清晰的层级输出:Planet: Earth Continent: Asia Country: China State: Guangdong City: Guangzhou
扩展优化思路
如果后续类结构有变动,或者想让函数更通用,可以不用硬编码对象类型,改成自动识别子属性的版本:
def list_all_objects_generic(obj, depth=0): indent = " " * depth print(f"{indent}{type(obj).__name__}: {obj.name}") # 约定好所有子集合属性的名称,自动查找 possible_child_attrs = ["continents", "countries", "states", "cities"] for attr in possible_child_attrs: if hasattr(obj, attr): children = getattr(obj, attr) for child in children: list_all_objects_generic(child, depth + 1) break
这个版本不用逐个判断对象类型,只要对象有对应的子属性就会自动遍历,灵活性更强。
内容的提问来源于stack exchange,提问作者Aaron Beaudoin
相关产品推荐
相关产品推荐

