python复习--对象相关--对象生命周期

一. 一句话总览版

Python 对象的生命周期是:
创建 → 被引用 → 引用变化 → 不可达 → 回收

Python 只关心“引用”,不关心“是否使用”。

二、Python 世界里最重要的 3 个概念

1.对象(Object)

  • 真正存在于内存中的东西
  • 例如:整数、字符串、函数、类、列表……

2.名字(Name / 变量名)

  • 只是一个引用标签
  • 本身不存数据

3.引用(Reference)

  • 名字 / 容器 / 属性 → 对象 的指向关系
    名字 ──▶ 对象
    名字 ≠ 对象

三、对象生命周期第 1 阶段:创建(Creation)

  • 对象只会在执行“创建语句”时创建。

1. 常见的创建方式

绑定名字

x ──▶ <listobject>

名字 x 指向这个 list 对象
引用计数 = 1Python 不会“先创建一个没有引用的对象,再找名字给它”
这两步在语义上是原子完成的。

创建对象

[]

在内存中创建一个 list 对象
对象此时 必须被某个引用接住

逐字拆解 x = [] 到“解释器视角”

x =[]

在这一行里,发生了 两个动作(但对你来说像一步):

示例

a =10# 创建 int 对象 b =[]# 创建 list 对象 c ={}# 创建 dict 对象 d =lambda x: x # 创建函数对象

[] 是对象本身(一个 list 对象)
b 不是对象,只是一个名字(引用)
b = [] 的含义是:
创建一个 list 对象,然后让名字 b 指向它

2. def / class 也是“创建对象”

执行到这行时:
创建函数 / 类对象
绑定名字

语法创建的对象绑定的名字
def f()函数对象f
class A类对象A

示例

deff():passclassA:pass

四、对象生命周期第 2 阶段:被引用(Alive)

1.示例

  • 内存关系:f ──▶ <function f>
  • 此时:
    引用数 ≥ 1
    对象是“活着的”
    GC 不会碰它

示例

deff():pass

2.引用是怎么变化的?(这是核心)

引用 -1 的情况

b =None

a ───▶ []
引用数 = 1(对象仍活着)

引用 +1 的情况

a =[] b = a 

a ─┐
├──▶ []
b ─┘
引用数 = 2

五、对象生命周期第 3 阶段:不可达(Unreachable)

1. 关键规则

当一个对象没有任何引用指向它时,它就“不可达”

示例

f =[] f =None

执行过程:
f = []:创建 list,对象被 f 引用 (引用=1)
f = None:解除引用 (引用=0)执行结束后:
没有任何名字指向该 list
引用计数 = 0
对象不可达
等待 / 立即回收(CPython)

2. 补充(需要注意)

不可达 ≠ 立刻销毁(在所有实现中)

CPython:引用计数 → 通常立刻回收
其他实现(PyPy):可能延迟回收

六、对象生命周期第 4 阶段:回收(Garbage Collection)

  • Python 的 GC 两层机制

1. 第一层:引用计数(最核心、最常用)

  • CPython 中,每个对象都有 refcount,这是 CPython 的基础机制。

什么是引用计数?
每个对象内部都有一个 refcount
每多一个引用,计数 +1
每少一个引用,计数 -1
当 refcount == 0 → 对象立刻销毁(大多数情况)
示例:

a =[] a =None

a = [] → 引用数 = 1
a = None → 引用数 = 0 → 回收

2. 第二层:循环垃圾回收(Cycle GC)

  • 为了解决循环引用,Python 引入了第二层机制。

即使这样:

a =None b =None

你会以为对象可以被回收,但实际上:a 和 b 互相引用
各自的 refcount 都不为 0
引用计数机制 无法回收它们

循环引用问题(引用计数解决不了)

a =[] b =[] a.append(b) b.append(a)

此时结构是:

 a → b ↑ ↓ └───┘ 

循环 GC 的核心思想
只要对象组“从程序中不可达”,就应该被回收
不管它们内部怎么互相引用。

a =[] b =[] a.append(b) b.append(a) a =None b =None
  • 此时:
    程序中已经没有任何变量能访问这两个列表
    虽然它们内部还互相引用
    循环 GC 会发现它们不可达,并最终回收

3. 表格记忆

机制解决什么特点
引用计数普通对象回收快、实时
循环 GC循环引用定期扫描、补救机制

99% 情况靠引用计数
1% 循环引用靠 GC 扫描

七、一个“完整生命周期时间线”示例(重点)

1. 示例

defmake(): x =[]return x a = make() b = a a =None b =None

执行过程:

时刻状态
x = []创建 list,对象一出生就被 x 引用,引用数 = 1
return x返回引用,返回的是对象的引用,不是新对象
a = make()a 指向 list,引用数 = 1
b = a引用 +1
a = None引用 -1
b = None引用 -1,引用 = 0 → 回收

这里的 a 和 b 这两个名字,绑定到了同一个 list 对象上

八、装饰器中的对象生命周期

1. 示例一:装饰器保存原函数引用

defdecorator(func):defwrapper(): func()return wrapper @decoratordeff():print("hi")

装饰器在函数定义阶段执行,等价于:

deff():print("hi")defdecorator(func):defwrapper(): func()return wrapper f = decorator(f)

逐步执行过程(对象 + 引用)

  1. 原函数为什么没被回收?
    因为:
    wrapper.closure → func → f_original
    虽然名字 f 不再指向原函数
    但 wrapper 闭包仍然引用它
    f_original 仍然存活
    总结一句话, 装饰器通过闭包,延长了原函数对象的生命周期

返回 wrapper 并重新绑定名字

f = wrapper 

原来的 f 名字不再指向 f_original
f → wrapper

创建 wrapper 函数对象

defwrapper(): func()

创建 wrapper 函数对象
wrapper 闭包捕获了 func
func → f_original

调用装饰器

decorator(f_original)

func 参数 → 引用 f_original

创建原函数对象

deff():print("hi")

创建 函数对象 f_original
名字 f → 绑定到 f_original

2. 示例二:装饰器不保存原函数引用

defdecorator(func):returnlambda:print("hi")@decoratordeff():print("hi")

等价于:

deff():print("hi")defdecorator(func):returnlambda:print("hi") f = decorator(f)

执行过程

  1. 创建原函数对象创建 f_original
    f → f_original
  2. 结果
    f_original 变为不可达对象
    引用计数 = 0
    立即被回收

名字重新绑定

f = lambda_func 

原来的 f 不再指向 f_original
没有任何引用指向 f_original

调用 decorator

decorator(f_original)

但 返回的 lambda 没有引用 func

3. 两种装饰器的“生命周期对比表”

情况原函数是否被保存原函数生命周期
wrapper 使用 func是(闭包)存活
不使用 func立即回收

九、对象“不会被回收”的常见原因

1. 还有全局引用

cache =[] cache.append(obj)

2. 被闭包捕获

defouter(): x =[]definner():return x return inner 

3. 存在循环引用 + del

classA:def__del__(self):pass

可能导致无法回收

十、你现在可以用这段话“完美描述对象生命周期”

Python 对象在执行创建语句时生成,
通过名字、容器或属性被引用;
在运行过程中引用动态变化;
当对象不再被任何引用指向时变为不可达;
随后由引用计数或 GC 回收,生命周期结束。

这是解释器级理解

十一、最终总结(必记)

Python 不关心是否调用
Python 不预测未来代码
Python 只在当前时刻检查引用
对象一旦不可达,永远无法复活

Read more

Flutter 三方库 at_server_status 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、实时的 @protocol 去中心化身份服务器状态感知与鉴权监控引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 at_server_status 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、实时的 @protocol 去中心化身份服务器状态感知与鉴权监控引擎 在鸿蒙(OpenHarmony)系统的隐私保护应用、去中心化身份管理工具(基于 @protocol 协议)或需要实时监控全球分布式节点健康状况的场景中,如何判定一个 @sign(电子签名标识)背后的 Root 服务器或 Secondary 服务器是否在线、配置是否由于由于由于由于已就绪?at_server_status 为开发者提供了一套工业级的、基于协议栈的状态审计与自检方案。本文将深入实战其在鸿蒙 Web3 身份安全底座中的应用。 前言 什么是 atServer Status?它是 @protocol(一种旨在让用户完全掌控数据的去中心化协议)官方生态的核心组件。

By Ne0inhk
鸿蒙金融理财全栈项目——生态合作、用户运营、数据变现

鸿蒙金融理财全栈项目——生态合作、用户运营、数据变现

《鸿蒙APP开发从入门到精通》第19篇:鸿蒙金融理财全栈项目——生态合作、用户运营、数据变现 📊🌍💰 内容承接与核心价值 这是《鸿蒙APP开发从入门到精通》的第19篇——生态合作、用户运营、数据变现篇,100%承接第18篇的风险控制、合规审计、产品创新架构,并基于金融场景的生态合作、用户运营、数据变现要求,设计并实现鸿蒙金融理财全栈项目的生态合作、用户运营、数据变现功能。 学习目标: * 掌握鸿蒙金融理财项目的生态合作设计与实现; * 实现金融机构合作、支付渠道合作、数据分析合作; * 理解用户运营在金融场景的核心设计与实现; * 实现用户增长、用户留存、用户转化; * 掌握数据变现在金融场景的设计与实现; * 实现数据服务、数据产品、数据变现; * 优化金融理财项目的用户体验(生态合作、用户运营、数据变现)。 学习重点: * 鸿蒙金融理财项目的生态合作设计原则; * 用户运营在金融场景的应用; * 数据变现在金融场景的设计要点。 一、 生态合作基础 🎯 1.1 生态合作定义 生态合作是指金融理财项目与其他金融机构、

By Ne0inhk

Flutter 三方库 encrypter_plus 的鸿蒙化适配指南 - 打造工业级多重加密隔离、安全存储实战、鸿蒙级数据隐私专家

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 encrypter_plus 的鸿蒙化适配指南 - 打造工业级多重加密隔离、安全存储实战、鸿蒙级数据隐私专家 在鸿蒙跨平台应用处理用户核心资产、敏感通讯或离线隐私数据库时,单一的加密手段往往难以应对复杂的逆向工程攻击。我们需要一套功能全面、算法严谨且易于在鸿蒙端进行多层加固的方案。今天我们要深度解析的 encrypter_plus——一个集成了 AES、RSA、Salsa20 等多种主流算法的增强型加密工具集,正是帮你构建“数据保险柜”的核心组件。 前言 encrypter_plus 是对经典 encrypt 库的功能增强与性能优化版。它提供了更直观的操作符抽象和更健壮的填充(Padding)机制。在鸿蒙端项目中,利用它你可以轻松实现前端文件加密、服务端通讯非对称握手以及本地敏感配置的字段级混淆,确保即使用户设备的物理文件被导出,数据依然处于不可读的“致密状态”。 一、原理解析 / 概念介绍 1.1

By Ne0inhk
终于把LLaMA 2跑起来了,然后呢?本地大模型部署的残酷真相!

终于把LLaMA 2跑起来了,然后呢?本地大模型部署的残酷真相!

“终于把LLaMA 2跑起来了!” 深夜11点,程序员小林在朋友圈晒出电脑屏幕截图——黑色命令行窗口里,一行行代码滚动后,本地大模型吐出了第一句回答。他兴奋地刷新着评论区,看着“大佬”“技术牛”的赞美,感觉自己摸到了AI时代的“核心门槛”。 可这份热情没能撑过一个月。如今,那台专门升级了显卡的电脑,大模型程序静静躺在硬盘深处,偶尔开机,也只是为了清理缓存。“生成一句话要等10秒,写周报还能把部门名写错,不如直接用GPT-4 API,3秒出结果还靠谱。”小林的话,道出了无数本地部署玩家的心声。 2023年以来,“本地部署大模型”成了AI圈的热门话题。从技术博主的“手把手教程”,到论坛里的“配置交流帖”,仿佛人人都能拥有一台“私人AI服务器”。但热闹背后,是一场无声的“弃坑潮”:某技术社区调研显示,70%的个人用户在部署完成后3个月内停止使用,曾经的“技术勋章”,最终沦为“电子垃圾”。 这股热情的消退,绝非偶然。当“掌控AI”

By Ne0inhk