You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类变量重置后值仍保留?Python类成员变量生命周期疑问

问题:类级列表属性导致多次调用结果污染的原因

先看这段会在不同二叉树上多次执行的代码:

class Solution:
    ans = []

    def getLonelyNodes(self, root: Optional[TreeNode]) -> List[int]:
        def helper(root):
            if root.left is None and root.right:
                self.ans.append(root.right.val)
                return helper(root.right)
            if root.left and root.right is None:
                self.ans.append(root.left.val)
                return helper(root.left)
            if root.left and root.right:
                return helper(root.left), helper(root.right)
            if root.left is None and root.right is None:
                return

        helper(root)
        ans = self.ans
        self.ans = []
        return ans

问题是:虽然在函数末尾重置了self.ans,但下次运行时结果里仍会保留之前的值,每次运行都会把旧结果追加到新结果里。把self.ans = []移到helper函数上方后问题解决了,但不明白为什么开头重置有效,末尾重置无效。


原因解析

核心问题出在类属性和实例属性的区别上:

  • 你定义的ans = []是类级别的属性,所有Solution类的实例都会共享这个列表对象,本质是一个全局共享的容器。
  • 当你第一次调用getLonelyNodes时:
    1. self.ans会先找当前实例有没有ans属性,因为实例没有,所以直接使用类的ans列表,往里面追加元素。
    2. 函数末尾执行self.ans = [],这一步是给当前实例新增了一个名为ans的实例属性,值是空列表,但类本身的ans列表还是原来那个存了旧结果的对象。
  • 如果下次调用时是创建了新的Solution实例:
    新实例没有自己的ans属性,会去读取类的ans,也就是之前被污染的那个旧列表,所以新结果会和旧结果混在一起。

而把self.ans = []移到函数开头后:

  • 每次调用getLonelyNodes时,都会先给当前实例绑定一个全新的空列表作为ans属性,后续self.ans.append()操作的都是这个实例自己的列表,和类的共享列表彻底无关。
  • 不管是同一个实例多次调用,还是创建新实例调用,每次操作的都是独立的空列表,自然不会出现旧结果残留的问题。

简单来说:末尾重置只是给当前实例“换了个新列表”,但类的共享列表没被清空;开头重置是每次都用实例自己的新列表,完全避开了类的共享属性。


内容的提问来源于stack exchange,提问作者Alec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:02:17