如何访问python实例方法对象的捕获参数/闭包?
其思想是以非泄漏/自动清理方式实现观察者模式。因此,当gc清理关联对象时,应该删除实例方法对象。如何访问python实例方法对象的捕获参数/闭包?,python,closures,weak-references,Python,Closures,Weak References,其思想是以非泄漏/自动清理方式实现观察者模式。因此,当gc清理关联对象时,应该删除实例方法对象。 我最初的想法是只存储对实例方法对象的弱引用,并使用终结器调用清理例程 可观测的类: 定义初始化(自): self.\u回调:list=[] self.\u dirty=False def添加_回调(自我,回调): 完成(回拨、自置、设置) self.\u callbacks.append(ref(callback)) def触发器_回调(self、*args、**kwargs): 如果自身不干净:
我最初的想法是只存储对实例方法对象的弱引用,并使用终结器调用清理例程
可观测的类:
定义初始化(自):
self.\u回调:list=[]
self.\u dirty=False
def添加_回调(自我,回调):
完成(回拨、自置、设置)
self.\u callbacks.append(ref(callback))
def触发器_回调(self、*args、**kwargs):
如果自身不干净:
self.\u cleanup\u callbacks()
对于self.\u回调中的回调:
回调()(*args,**kwargs)
def_设置_脏(自):
self.\u dirty=True
def_cleanup_回调(自):
对于self.\u回调中的回调:
如果不是回调():
self.\u回调。删除(回调)
self.\u dirty=False
然而,事实证明,这种方法在概念上是有缺陷的,因为实例方法对象的生命周期没有绑定到关联对象
这让我想到了从实例方法对象的闭包中提取self参数并绑定到其生存期。当然,这可以通过向add_callback传递第二个参数来完成,但是从闭包中提取它会更干净
由于我找不到任何关于闭包如何存储在函数对象中的有用信息,我有几个问题想问你们
我希望我的问题/问题是清楚的,提前谢谢你的帮助 @fountainhead主要是用他的评论来回答这个问题,所以我将很快进行总结 方法中的函数对象正式称为“实例方法对象”(,搜索方法对象) 因此1。它将阻止gc清理关联的对象。 2.可通过
\uuuu self\uuu
和3访问。上面已经给出了答案
为了使Observable类按照我的预期工作,我基本上将函数名和weakref保存到\uuuuself\uuuu
中,然后使用getattr()
调用它。工作起来很有魅力
from weakref import finalize, ref
from functools import partial
class Observeable:
def __init__(self):
self._methods: list = []
self._functions: list = []
self._dirty = False
def add_callback_methode(self, callback):
"""
Adds a callback from a method.
The callback will automatically be cleanup,
when its associated objects gets out of scope,
therefor also not preventing the gc from cleaning it up.
"""
finalize(callback.__self__, self._set_dirty)
self._methods.append((callback.__name__, ref(callback.__self__)))
def trigger_callbacks(self, *args, **kwargs):
"""Forwards the given args and kwargs to all callbacks"""
if self._dirty:
self._cleanup_callbacks()
for callback in self._methods:
getattr(callback[1](), callback[0])(*args, **kwargs)
def _set_dirty(self):
self._dirty = True
def _cleanup_callbacks(self):
for callback in self._methods:
if not callback[1]():
self._methods.remove(callback)
self._dirty = False
我还认为,当方法的函数对象存储对源对象的引用时,不管函数是否只是弱引用,这都会阻止它被清除。因此,我想这样一个无需手动取消订阅即可观察到的自动清理是根本不可能的?函数对象没有
self
对象作为其属性之一。只有方法
对象才有self
对象作为其属性之一,尽管我不确定该属性的确切名称。您的回调是否需要存储为对函数的引用,还是需要存储为对方法的引用?@fountainhead是的,我只是说函数对象到方法,sry如果不清楚,我觉得应该存储对方法对象而不是函数对象的引用。(如果同一类的两个实例想要向同一个可观察对象添加相同的回调函数怎么办?)__订户对象的方法。