Python实例方法递归调用时能否用其他实例替代self参数?
结论
这种写法完全不违反Python语法规则,你当前贴出的代码存在递归传参的逻辑错误,并非语法层面不支持切换实例调用方法。
原理说明
Python实例方法的第一个self参数只是约定俗成的命名,本质是隐式传入的调用方实例:哪个实例调用方法,self就会自动绑定到哪个实例,没有规则要求递归时必须用最初的self作为调用方。只要parent是和当前self同类型、具备get_ancestors方法、以及links/tree相关属性的实例,用parent.get_ancestors()做递归调用是完全合法的。
你当前的代码运行会直接报错,原因是递归调用写法不符合方法签名定义:
- 你定义的
get_ancestors方法,显式需要传入的参数只有ancestors一个(self是调用时自动绑定的隐式参数) - 你写的
self.get_ancestors(parent, ancestors)传入了2个显式参数,加上隐式绑定的初始self,总共传了3个参数,会触发TypeError: get_ancestors() takes 2 positional arguments but 3 were given报错;同时这行代码始终用初始实例做递归,也不符合你「后续迭代用parent实例调用」的需求。
修正后可运行代码
def get_ancestors(self, ancestors): parents = [] for uid in self.links: parents.append(self.tree.find_item(uid)) for parent in parents: if parent.links: # 直接用parent实例调用,方法内的self会自动绑定为当前parent,仅需传入ancestors一个显式参数 parent.get_ancestors(ancestors) else: if parent not in ancestors: ancestors.append(parent) return ancestors
使用提示
- 调用方法时需要先传入初始化的空列表作为祖先收集容器,示例:
ancestor_list = root_item.get_ancestors([]) - 去重逻辑当前是靠
parent not in ancestors判断,如果你存储的节点实例是可哈希的,后续也可以换用set做收集提升去重效率,不过要注意最终返回结果的顺序问题。
内容的提问来源于stack exchange,提问作者bree pav
相关产品推荐
相关产品推荐

