微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何访问捕获的参数/ python实例方法对象的关闭?

如何解决如何访问捕获的参数/ python实例方法对象的关闭?

这个想法是以非泄漏/自动清理的方式实现Observer模式的。因此,当gc清除关联的对象时,应删除实例方法对象。
我最初的想法是只使用终结器存储对实例方法对象的弱引用,以调用清除例程。

class Observeable:
    def __init__(self):
        self._callbacks: list = []
        self._dirty = False

    def add_callback(self,callback):
        finalize(callback,self._set_dirty)
        self._callbacks.append(ref(callback))

    def trigger_callbacks(self,*args,**kwargs):
        if self._dirty:
            self._cleanup_callbacks()
        for callback in self._callbacks:
            callback()(*args,**kwargs)

    def _set_dirty(self):
        self._dirty = True

    def _cleanup_callbacks(self):
        for callback in self._callbacks:
            if not callback():
                self._callbacks.remove(callback)
        self._dirty = False

事实证明,由于实例方法对象的生命周期未绑定到关联的对象,因此该方法在概念上存在缺陷。

这使我想到了从实例方法对象的关闭提取self参数并绑定其生存期的想法。当然,这可以通过将第二个参数传递给add_callback来完成,但是从闭包中提取它会更清洁。

由于我无法找到有关闭包如何存储在函数对象中的任何有用信息,因此我对您有一些疑问。

  1. 我的想法是否正确?存储实例方法对象将防止自动清除后面的对象,对吗?
  2. 是否可以从函数对象中提取self参数/一般闭包?
  3. 功能对象是否有一个更“正式”的名称? python docu也只是这样称呼它,但是似乎没有关于它的更底层实现的有用信息。

我希望我的问题很清楚,谢谢您的提前帮助!

解决方法

@fountainhead大多以他的评论回答了这个问题,所以我将在短期内总结一下。

方法中的功能对象正式称为“实例方法对象”(https://docs.python.org/3/reference/datamodel.html,搜索方法对象)

因此1.它将防止gc清除关联的对象。 2.可以由__self__访问,并且3.上面已经回答了。

要使Observable Class像我预期的那样工作,我基本上将函数名称和一个weakref保存到__self__,然后用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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。