当前位置: 首页 > news >正文

python引用计数的增加和减少

在 Python 中,引用计数的变动本质是 “普通引用的新增”或“普通引用的移除”——任何导致“指向对象的普通引用数量变化”的操作,都会直接引发引用计数的变动。以下是所有核心场景的分类梳理,结合案例帮助理解:

一、引用计数「增加」的场景(新增普通引用)

只要有新的“普通引用”指向对象,计数就会 +1。普通引用的核心是“能维持对象存活的关联关系”(弱引用不算),具体场景包括:

1. 变量与对象绑定(最基础)

当变量通过赋值指向对象时,会建立“变量→对象”的普通引用,计数 +1。
案例

class Node:def __init__(self, name):self.name = name# 1. 创建对象并绑定变量a:objA的引用计数从0→1
a = Node("A")  
# 2. 变量b也指向objA:新增引用,计数从1→2
b = a          
2. 对象属性指向其他对象

当一个对象的属性(如 self.nextself.attr)指向另一个对象时,会建立“属性→对象”的普通引用,计数 +1。
案例

objA = Node("A")  # 计数1(变量objA)
objB = Node("B")  # 计数1(变量objB)# objA的next属性指向objB:objB的计数从1→2
objA.next = objB  
3. 容器添加对象元素

当对象被添加到列表(list)、字典(dict,作为值)、集合(set)等容器中时,会建立“容器元素→对象”的普通引用,计数 +1。
案例

objA = Node("A")  # 计数1(变量objA)
lst = []# 列表添加objA:新增容器元素引用,计数从1→2
lst.append(objA)  
# 字典值添加objA:再新增引用,计数从2→3
dct = {"key": objA}  
4. 函数参数传递

当对象作为实参传递给函数时,会建立“函数形参→对象”的普通引用,计数 +1(函数执行期间有效,执行结束后形参销毁,引用移除)。
案例

import sysdef check_count(obj):# 函数内形参obj指向传入的对象,计数会+1(此处打印时需减2:函数形参+sys.getrefcount的临时引用)print(f"函数内计数:{sys.getrefcount(obj) - 2}")objA = Node("A")  # 计数1
check_count(objA)  # 传入objA,形参obj新增引用,函数内计数为1(原1 + 形参1 - 临时引用2)
5. 函数返回对象

当函数返回对象并被接收时,会建立“接收变量→返回对象”的普通引用,计数 +1。
案例

def create_node():# 函数内创建obj,计数1(变量obj)obj = Node("A")  return obj  # 返回obj,函数结束后内部变量obj销毁,计数降为0→但外部接收会新增引用# 外部变量res接收返回值:新增引用,obj的计数从0→1
res = create_node()  

二、引用计数「减少」的场景(移除普通引用)

当指向对象的普通引用被销毁或切断时,计数会 -1。当计数降至 0 时,对象会被 Python 垃圾回收(GC)机制回收。

1. 变量被删除(del 语句)

del 变量 会销毁“变量→对象”的引用关系,若该变量是对象的普通引用来源,计数 -1。
案例

objA = Node("A")  # 计数1(变量objA)
del objA  # 销毁objA的引用,计数从1→0→对象被回收
2. 变量重新绑定

当变量从指向旧对象,改为指向新对象时,旧对象的“变量引用”被切断,计数 -1。
案例

objA = Node("A")  # 计数1(objA)
objB = Node("B")  # 计数1(objB)# 变量objA重新指向objB:旧对象objA的引用被切断,计数从1→0→回收;objB的计数从1→2
objA = objB  
3. 对象属性被删除或重新赋值
  • del 对象.属性:销毁“属性→原指向对象”的引用,原对象计数 -1;
  • 对象.属性 = 新值:切断“属性→原对象”的引用,原对象计数 -1,新值对象计数 +1。
    案例
objA = Node("A")  # 计数1
objB = Node("B")  # 计数1
objA.next = objB  # objB计数从1→2(属性引用)# 情况1:删除objA.next属性→objB的引用被切断,计数从2→1
del objA.next  # 情况2:重新赋值objA.next→objB的引用被切断(计数2→1),新对象Node("C")计数+1
objA.next = Node("C")  
4. 容器移除元素或容器被销毁
  • 容器移除元素(如 lst.pop()del lst[index]):切断“容器元素→原对象”的引用,原对象计数 -1;
  • 容器被销毁(如 del lst):若容器内元素指向对象,容器销毁后所有“元素→对象”的引用被切断,对象计数 -= 元素中引用的数量。
    案例
objA = Node("A")  # 计数1
lst = [objA]      # objA计数从1→2(列表元素引用)# 情况1:移除列表元素→objA计数从2→1
lst.pop(0)  # 情况2:销毁列表→列表元素的引用被切断,objA计数从2→1
del lst  
5. 函数执行结束(形参/局部变量销毁)

函数执行结束后,函数内的局部变量(包括形参)会被销毁,它们指向对象的引用被切断,对象计数 -= 局部变量中引用的数量。
案例

def func(obj):# 函数内形参obj指向传入的objA,objA计数+1(假设外部计数1,此处变为2)temp = obj  # 局部变量temp指向objA,计数从2→3# 外部调用函数
objA = Node("A")  # 计数1
func(objA)        # 函数执行结束后,形参obj、局部变量temp销毁→objA计数从3→1

三、特殊情况:引用计数「不变」的场景

以下操作看似关联对象,但不会新增/移除普通引用,因此计数不变:

  1. 弱引用操作weakref.ref(obj)weakref.proxy(obj)——弱引用不参与引用计数,仅跟踪对象,不会让计数增减;
  2. 对象属性访问obj.name(仅读取属性,不建立新引用,也不销毁旧引用);
  3. 容器遍历for item in lst(遍历仅读取元素,不新增对元素指向对象的引用);
  4. 小整数/短字符串缓存a = 10; b = 10——小整数(-5~256)和短字符串会被 Python 缓存,b = 10 不会创建新对象,仅绑定已有缓存对象,因此缓存对象的计数会 +1(但本质仍是变量绑定的普通引用,属于“计数增加”场景,只是对象是缓存的)。

四、总结:引用计数变动的核心规律

变动方向本质原因典型场景举例
增加新增「普通引用」指向对象变量绑定、属性赋值、容器添加元素
减少移除「普通引用」指向对象删除变量、属性删除、容器移除元素
不变无普通引用的新增/移除弱引用操作、属性访问、遍历容器

理解这些场景的关键是:判断操作是否会新增或移除“能维持对象存活的普通引用”——只要涉及普通引用的变化,引用计数就会随之变动;反之则不变。当引用计数降至 0 时,对象会被立即回收(仅考虑引用计数机制,不考虑分代回收)。

http://www.dtcms.com/a/404354.html

相关文章:

  • 重庆做网站好的公司怎么搭建自己的电影网站
  • 网站建设包括的内容有什么宁波网页平面设计
  • 龙岗网站建设推广中国城乡和住房建设部网站首页
  • 网站黄页推广软件专业网页制作平台
  • 张家港建设局官方网站wordpress采集英文
  • 宁夏做网站的公司谷歌浏览器官网下载安装
  • 移动网站设计教程如何绑定网站域名
  • 门户网站价格网络营销的主要特点有哪些
  • thinkphp 企业网站源码仙桃网站制作州国
  • 网站开发验收报告模板自己在线制作logo免费圆形
  • 建设银行网站扫码支付在哪里外贸网站风格
  • 域名免费注册网站什么是电商视觉设计
  • 无锡阳山镇网站建设上海材料网站建设
  • 淄博网站建设公司推荐电子商务网站建设方案推荐
  • 宁波企业网站搭建极速建站免费创建网站的平台
  • 用家用路由器ip做网站网站开发与维护好找工作吗
  • 公司网站的seo优化怎么做网站建设的好处和目的
  • 做网站大公司建立网站用什么软件
  • 【STC51项目开源】STC51单片机智能台灯控制系统
  • 衡水林熠网站建设公司wordpress自带的简码
  • TDengine 聚合函数 HISTOGRAM 用户手册
  • 网站建设专题的意义软装设计师培训机构
  • 怎么做返利网站吗郑州短视频拍摄制作公司
  • 广州市从化区住房和建设局网站品牌形象设计方案
  • 郑州网站建设国奥大厦ui网页设计规则
  • 云企网站seo页面优化技术
  • 福州正规网站建设公司报价网盘 wordpress模板
  • 网络营销成功的案例及其原因郴州网站seo外包
  • 现在流行做网站吗wordpress添加加载中
  • git报错:Unlink of file ‘‘ failed. Should I try again? (y/n)