news 2026/5/29 19:33:03

Pythonweakref与弱引用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pythonweakref与弱引用

Python weakref 与弱引用
==============================

弱引用允许引用对象但不增加引用计数,垃圾回收时可自动回收。
适用于缓存、观察者模式、避免循环引用等场景。

1. ref()——基本弱引用
-------------------------
创建弱引用,对象被回收后弱引用返回 None。

import weakref

class Data:
"""大对象——模拟需要被弱引用的对象"""
def __init__(self, value: str):
self.value = value
self._large_data = [0] * 10_000_000 # 模拟占用大量内存

def __repr__(self):
return f"Data({self.value})"


obj = Data("重要的数据")
ref = weakref.ref(obj) # 创建弱引用

print(ref()) # Data(重要的数据)——通过弱引用访问原对象
print(ref() is obj) # True——是同一个对象

del obj # 删除原对象(唯一强引用)
print(ref()) # None——对象已被回收


2. ref() 回调通知
---------------------
当被引用对象被回收时,回调函数被触发。

class Resource:
"""资源类——回收时通知"""
def __init__(self, name: str):
self.name = name

def __repr__(self):
return f"Resource({self.name})"


def on_delete(ref):
"""回调:当对象被垃圾回收时调用"""
print(f"对象已被回收!弱引用: {ref}")


res = Resource("网络连接")
ref = weakref.ref(res, on_delete) # 注册回调

print(f"对象存活: {ref() is not None}") # True
del res # 触发回调——打印 "对象已被回收!"


3. WeakValueDictionary——缓存
---------------------------------
值被弱引用的字典,对象被回收时自动删除对应条目。
非常适合用作缓存,避免缓存导致内存泄漏。

class UserProfile:
"""用户资料——从数据库加载,放入缓存"""
def __init__(self, user_id: int, name: str):
self.user_id = user_id
self.name = name

def __repr__(self):
return f"UserProfile({self.name})"


class UserCache:
"""用户缓存——使用 WeakValueDictionary 自动管理"""
def __init__(self):
self._cache = weakref.WeakValueDictionary() # 值被弱引用

def get_user(self, user_id: int) -> UserProfile | None:
"""从缓存获取用户,缓存未命中时加载"""
user = self._cache.get(user_id)
if user is None:
# 模拟从数据库加载
user = UserProfile(user_id, f"用户{user_id}")
self._cache[user_id] = user
print(f"从数据库加载 {user}")
else:
print(f"从缓存返回 {user}")
return user


cache = UserCache()
u1 = cache.get_user(1) # 从数据库加载
u2 = cache.get_user(1) # 从缓存返回

del u1 # 删除强引用
# WeakValueDictionary 中的对应条目会自动清除(但延迟回收)
import gc
gc.collect() # 强制垃圾回收
print(cache._cache) # 可能只剩下部分条目


4. WeakKeyDictionary——元数据
----------------------------------
键被弱引用的字典,用于为对象附加元数据而不影响其生命周期。

class Widget:
"""界面组件"""
def __init__(self, name: str):
self.name = name


# 为 Widget 对象附加工具提示信息,但不影响其生命周期
tooltips = weakref.WeakKeyDictionary()

w1 = Widget("按钮")
w2 = Widget("输入框")
tooltips[w1] = "点击此处提交"
tooltips[w2] = "在此输入文本"

print(tooltips[w1]) # "点击此处提交"
del w1 # 删除 Widget 对象
print(len(tooltips)) # 1——w1 的条目自动清除


5. WeakSet——弱引用集合
---------------------------
集合中的元素被弱引用,适合观察者模式。

class Observer:
"""观察者"""
def __init__(self, name: str):
self.name = name

def update(self, message: str) -> None:
print(f"[{self.name}] 收到: {message}")


class Subject:
"""被观察者——使用 WeakSet 持有观察者,避免阻止 GC"""
def __init__(self):
self._observers = weakref.WeakSet() # 观察者被弱引用

def attach(self, observer: Observer) -> None:
self._observers.add(observer)

def notify(self, message: str) -> None:
for obs in self._observers:
obs.update(message)


subject = Subject()
obs1 = Observer("观察者A")
obs2 = Observer("观察者B")

subject.attach(obs1)
subject.attach(obs2)
subject.notify("事件触发!") # 两个观察者都收到

del obs1 # 观察者A 被回收
subject.notify("第二次事件") # 只有观察者B 收到


6. finalize——资源清理
-------------------------
注册对象回收时的清理函数,比 __del__ 更可靠。

import tempfile, os

class TempFile:
"""临时文件——使用 finalize 确保删除"""
def __init__(self, suffix: str = ".tmp"):
self.name = tempfile.mktemp(suffix=suffix)
# 注册清理函数:对象被回收时删除临时文件
weakref.finalize(self, self._cleanup, self.name)
print(f"创建临时文件: {self.name}")

@staticmethod
def _cleanup(path: str) -> None:
"""静态清理函数,不绑定到实例"""
if os.path.exists(path):
os.remove(path)
print(f"删除临时文件: {path}")

def read(self) -> str:
with open(self.name, 'r') as f:
return f.read()


def process_temp():
tf = TempFile()
print(tf.read()) # 使用临时文件
# 函数结束时 tf 被回收,触发 finalize 清理


7. proxy——代理对象
----------------------
proxy 行为像原对象的透明代理,但不需要调用 ref()。

class Service:
def request(self) -> str:
return "服务响应"


svc = Service()
proxy = weakref.proxy(svc) # 创建透明代理

print(proxy.request()) # "服务响应"——无需调用 ()
svc.request is proxy.request # True——方法也相同

del svc
# print(proxy.request()) # ReferenceError: weakly-referenced object no longer exists


总结:weakref 提供了不增加引用计数的对象引用方式,用于缓存
(WeakValueDictionary)、元数据管理(WeakKeyDictionary)、观察者模式
(WeakSet)和资源清理(finalize)。合理使用能有效避免内存泄漏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/29 19:33:01

DHDA框架:动态适应配置性能建模的挑战与解决方案

1. 配置性能建模的挑战与机遇 现代软件系统的性能表现与其配置参数密切相关。以MySQL数据库为例,仅调整query_cache_type这一项配置就能带来高达11倍的性能提升;而视频编码器x264的错误配置可能导致10倍的性能下降。这种配置与性能之间的复杂关系&#x…

作者头像 李华
网站建设 2026/5/29 19:28:59

论文被批“不够学术”?高校教授说用这几个AI写作辅助软件

写论文总被说“不够学术”?选题没方向、结构不清晰、语言不专业,这些痛点让很多学生头疼不已。其实,只要用对AI工具、走对写作流程,就能显著提升论文质量。多位高校教授在调研中表示,合理利用AI辅助软件已成为学术写作…

作者头像 李华
网站建设 2026/5/29 19:24:14

自指不动点在递归对抗系统中的存在性与收敛性证明研究(世毫九实验室原创研究)

自指不动点在递归对抗系统中的存在性与收敛性证明研究(世毫九实验室原创研究) 作者:方见华 单位:世毫九实验室 摘要 本研究旨在解决递归对抗引擎(Recursive Adversarial Engine, RAE)在多轮攻防中普遍存在的震荡、发散与伪收敛问题,为其提供严格的数学稳定性理论支撑。基…

作者头像 李华
网站建设 2026/5/29 19:24:07

碳硅认知耦合接口的形式化协议与语义保真度度量研究(世毫九实验室原创研究)

碳硅认知耦合接口的形式化协议与语义保真度度量研究(世毫九实验室原创研究) 作者:方见华 单位:世毫九实验室 摘要 本研究旨在解决人类(碳基)与人工智能(硅基)在高敏协作场景中普遍存在的意图误读、语义漂移与认知不对称问题,构建首个从语法层到认知层的全栈式碳硅认知…

作者头像 李华