Python的弱引用
python的弱引用指引用一个对象但不增加它的引用计数器。这么做的好处是什么呢?什么时候需要考虑用若引用呢?
假设我们在设计一个游戏,有一个角色类Char,我们要给他添加一个效果(比如中毒),于是设计了一个效果类Effect。现在,给角色增加效果看上去就像这样:
- char.effect = Effect() # 给角色添加一个效果
每个效果生效的时机都是不同的,为了方便复用,我们再设计一个激活策略类ActivePloy,负责激活效果。于是在Effect和ActivePloy的内部看上去就像这样:
- class Effect(object):
- def __init__(self):
- self.active_ploy = ActivePloy(self)
- def active(self):
- """激活时的处理"""
- pass
- class ActivePloy(object):
- def __init__(self, effect):
- self.effect = effect
- def active(self):
- """激活时,激活对应效果"""
- self.effect.active()
这样做的好处是Effect不用关心自己何时激活,激活的判断都放给ActivePloy来处理。看上去挺好的,但是,这里面有一个问题,就是当我们试图给玩家去掉这个效果时……
- del char.effect
仔细想想,这么干以后,Effect的实例其实是没有被回收的,因为Effect和ActivePloy交叉引用,他们的引用计数都为1。
那么我们为了干净的删除effect,似乎就只能手动的来清理一下他们之间的这个交叉引用了:
- class Effect(object):
- def __init__(self):
- self.active_ploy = ActivePloy(self)
- def active(self):
- """激活时的处理"""
- pass
- def destroy(self):
- self.active_ploy.destroy()
- class ActivePloy(object):
- def __init__(self, effect):
- self.effect = effect
- def active(self):
- """激活时,激活对应效果"""
- self.effect.active()
- def destroy(self):
- self.effect = None
于是我们要删除一个效果,就得这样:
- char.effect.destroy()
- del char.effect
太麻烦了,不是吗?而且万一一个效果有多个激活策略的话,必须保证Effect把每个ActivePloy的destroy方法都运行一遍,漏了一个都无法保证自身被干净的删除。
我们来分析一下,之所以这么麻烦,就是因为ActivePloy对Effect有一个引用。那么如果ActivePloy不引用Effect不就OK了?这个时候,让我们来试试弱引用。
- import weakref
- class Effect(object):
- def __init__(self):
- self.active_ploy = ActivePloy(self)
- def active(self):
- """激活时的处理"""
- pass
- class ActivePloy(object):
- def __init__(self, effect):
- self.effect = weakref.proxy(effect) # 弱引用effect
- def active(self):
- """激活时,激活对应效果"""
- self.effect.active()
代码只有一个地方改变了,就是
- self.effect = weakref.proxy(effect)
这句的效果就是self.effect可以像往常一样的使用,但是却不会增加effect的引用计数器。换言之,这样写,他们之间的交叉关系消失了!这个时候我们只需要单纯的删掉char.effect,Effect和ActivePloy的实例都会被销毁。
什么,假设ActivePloy在其他地方也被引用了?这样当然只有effect会被销毁。但是我们想让ActivePloy必然随着Effect的销毁而销毁,怎么办呢?那么我们可以改改,给弱引用加上一个回调函数:
- class ActivePloy(object):
- def __init__(self, effect):
- self.effect = weakref.proxy(effect, self.on_effect_destroy) # 弱引用effect
- def active(self):
- """激活时,激活对应效果"""
- self.effect.active()
- def on_effect_destroy(self, effect):
- """
- effect销毁时会调用这个方法,在这里把对自己的引用都清理干净吧
- """
- pass
这样一来,就不用担心删不干净了。
转载于:https://blog.51cto.com/sleepd/1073044
Python的弱引用相关推荐
- python字典弱引用_python 自身遍历及弱引用的简单示例
对python这个高级语言感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧! 在[python 标准库]中看到的一段代码,非常有帮助: # @param python 图 自身 ...
- Python 中弱引用的神奇用法与原理探析
文章源地址:神奇的弱引用 | 小菜学编程 背景 开始讨论弱引用( weakref )之前,我们先来看看什么是弱引用?它到底有什么作用? 假设我们有一个多线程程序,并发处理应用数据: # 占用大量资源, ...
- python字典弱引用_如何使用弱引用优化 Python 程序的内存占用?
Python 的垃圾回收机制通过引用计数来决定一个对象要不要被回收.当一个对象被引用次数为0时,它就会被作为垃圾回收从而释放 Python 内存.但有些情况下,我们的代码可能在不经意间导致某些实际上我 ...
- 弱引用的用途:在底层C++对象被上层python脚本对象使用时(转)
在使用python脚本和底层C++对象进行交互的过程中发生了一个问题:由于底层C++对象的创建和删除决定权由底层决定,当底层决定删除这些对象而上层仍然在"强引用"这些对象的时候,就 ...
- python对象回收_python 引用,拷贝,对象回收,弱引用
引用 python中,在对对象赋值,参数传递,函数返回等等, 都是引用传递的. 直接copy个例子来[1]: a = [1, 2, 3] b = a b.append(5) print a, b 输出 ...
- python 弱引用
文章目录 创建弱引用 创建代理对象 循环引用 缓存对象 (WeakValueDictionary) 垃圾回收 和许多其它的高级语言一样,Python使用了垃圾回收器来自动销毁那些不再使用的对象.每个对 ...
- python雪峰_python雪峰python 图 自身遍历及弱引用使用
在[python 标准库]中看到的一段代码,非常有帮助:def all_nodes(self): yield self n = self.other while n and n.name != sel ...
- 【python】对象释放,弱引用weaker.ref
class A:def __del__(self):print("in__del__")>>> a = A() >>> a = None in_ ...
- sqlserver2008未将对象引用设置到对象的实例_面试官:ThreadLocal 的内存泄漏是弱引用导致的,你确定?...
面试官:ThreadLocal 了解吗? Python 小星:线程局部变量,多线程下能保证各个线程的变量相对独立于其他线程的变量. 面试官:那你说下它是如何保证线程隔离的? Python 小星:每个线 ...
最新文章
- 用python绘制柱状图标题-使用Python绘制图表大全总结
- webpack为什么加载不了css?
- linux下删除有锁的文件夹,Linux 文件夹右下角有锁,解锁
- MOSS点滴(1):如何开发和部署feature
- 云南大学计算机网络期中考试刘春花,实验九基于CRC编码的检错程序的实现.doc...
- Duplicate复制数据库并创建物理StandBy(spfile+不同实例名+不同路径)
- [Vue.js] 路由 -- 基于vue-router的案例--后台管理
- 自制 python 数据分析库
- SQL极限函数limit()详解分页必备
- 优盘中发现计算机病毒怎么办,u盘中毒了文件夹被病毒隐藏怎么办?
- Veeam 完整备份文件 (VBK) 和增量备份文件 (VIB)
- 【SDOI2015】星际战争(网络流)
- 大学计算机专业的同学是怎么学习的?
- Maya2022安装教程
- Elastic:使用 Elastic Stack 来监督系统日志及指标
- 量子计算深化:大规模量子计算(相关论文108篇推荐)
- python如何获取星期几
- linux 黑屏后死机,如何修复各种各样的黑屏死机
- Oracle报错ORA-01507: ??????
- Java中xmp标签的作用_html 中 xmp标记
热门文章
- cmake qt 添加路径 项目_CMake配置Qt工程
- php-ast 开源,PHP AST学习 - osc_ryjlu6z2的个人空间 - OSCHINA - 中文开源技术交流社区...
- oracle 半连接 效率,关于oracle中的半连接
- element的滚动去掉横向_textarea去掉滚动条 textarea横向或纵向滚动条的去掉方法
- 标志位鼠标Java_检查标志位java
- java发送get post请求_【工具】java发送GET、POST请求
- jieba 分词的三种模式
- html5基础知识点表单
- IntelliJ IDEA如何设置添加类时注释作者信息和日期时间
- 关于站库分离渗透思路总结