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

Python重复赋值同名类实例变量异常输出及计数错误原因求解

执行逻辑解释

核心原因是Python的引用计数垃圾回收规则和类的__del__析构方法的触发机制,逐步骤拆解如下:

第一步:首次执行 p1 = Person('p1')

  • 新建Person实例,触发__init__方法打印Initializing p1,类属性population从0变为1
  • 变量p1指向这个新实例,实例引用计数为1,不会触发析构,无额外输出,符合预期。

第二步:第二次执行 p1 = Person('p1')

赋值操作的执行顺序是先计算等号右侧的值,再做变量绑定,所以执行流程为:

  1. 先执行Person('p1')创建第二个Person实例,触发__init__打印Initializing p1,population加1变为2
  2. 将新实例绑定到变量名p1,此时原来p1指向的第一个实例失去这个引用,引用计数降为0,触发第一个实例的__del__方法
  3. 第一个实例的__del__执行时打印p1 says bye,population减1变为1,因此打印there are still 1 people left
    这就是你看到两行输出的原因。

第三步:执行 p1 = Person('p2')仅输出初始化内容、howMany()返回2的原因

此时赋值时旧实例(第二步创建的第二个Person实例)没有触发__del__,说明该实例的引用计数没有降到0,常见于交互式运行环境(比如Jupyter Notebook、IPython):这类环境会缓存历史输入输出对象,持有实例的额外引用,导致旧实例不会被回收。
此时存活的实例有2个:第二步创建的未被回收的实例、刚创建的p2实例,因此howMany()返回2。

补充说明

  • 不要在业务逻辑中依赖__del__的执行时机,不同Python运行环境的垃圾回收行为可能存在差异,__del__仅在实例引用计数归0时才会被触发。
  • population是类级别的共享属性,所有实例共享同一个值,变化对所有实例可见。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:45:02