首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在Python中实现hook或回调的首选方式是什么?

在Python中实现hook或回调的首选方式是什么?

提问于 2018-02-27 20:19:19
回答 2关注 0查看 566

我想为我的某个模块的用户提供能力,通过提供一个调用用户函数的接口来扩展其功能。例如,我想让用户能够在创建类的实例时得到通知,并且有机会在实例使用之前修改实例。

我实现它的方式是声明一个实例化的模块级工厂函数:

代码语言:txt
AI代码解释
复制
# in mymodule.py
def factory(cls, *args, **kwargs):
    return cls(*args, **kwargs)

后来,当我需要一个MyModule的类的实例,我做的factory(cls, arg1, arg2)不是cls(arg1, arg2)

为了扩展它,程序员会在另一个模块中写入如下的函数:

代码语言:txt
AI代码解释
复制
def myFactory(cls, *args, **kwargs):
    instance = myFactory.chain(cls, *args, **kwargs)
    # do something with the instance here if desired
    return instance

以上回调的安装如下所示:

代码语言:txt
AI代码解释
复制
myFactory.chain, mymodule.factory = mymodule.factory, myFactory

这对我来说似乎很简单,但我想知道,作为一名Python程序员,是否希望函数能够注册回调函数,而不是使用赋值工具进行注册,或者如果还有其他方法可以使用。

我期待尽可能简单; 例如,我不认为大多数应用程序实际上需要链接多个用户回调(尽管无限制的链接是通过上述模式“免费”的)。我怀疑他们需要删除回调或指定优先级或顺序。像python-callbacksPyDispatcher这样的模块对我来说似乎过于矫枉过正了,尤其是后者,但是如果对于使用我的模块的程序员有很大的好处,我会向他们开放。

回答 2

想念o默默

发布于 2018-02-28 06:15:56

使用装饰器,维护附加回调列表的类,再加上从C#借用的概念,我得出了如下结论:

代码语言:txt
AI代码解释
复制
class delegate(object):

    def __init__(self, func):
        self.callbacks = []
        self.basefunc = func

    def __iadd__(self, func):
        if callable(func):
            self.__isub__(func)
            self.callbacks.append(func)
        return self

    def callback(self, func):
        if callable(func):
            self.__isub__(func)
            self.callbacks.append(func)
        return func

    def __isub__(self, func):
        try:
            self.callbacks.remove(func)
        except ValueError:
            pass
        return self

    def __call__(self, *args, **kwargs):
        result = self.basefunc(*args, **kwargs)
        for func in self.callbacks:
            newresult = func(result)
            result = result if newresult is None else newresult
        return result

@delegate允许其他功能“附加”到它。

代码语言:txt
AI代码解释
复制
@delegate
def intfactory(num):
    return int(num)

函数可以添加到委托+=(和删除-=)。你也可以用装饰funcname.callback来添加一个回调函数。

代码语言:txt
AI代码解释
复制
@intfactory.callback
def notify(num):
    print "notify:", num

def increment(num):
    return num+1

intfactory += increment
intfactory += lambda num: num * 2

print intfactory(3)   # outputs 8

最爱开车啦

发布于 2018-02-28 04:31:02

代码语言:txt
AI代码解释
复制
class C(object):
  _oncreate = []

  def __new__(cls):
    return reduce(lambda x, y: y(x), cls._oncreate, super(C, cls).__new__(cls))

  @classmethod
  def oncreate(cls, func):
    cls._oncreate.append(func)

c = C()
print hasattr(c, 'spew')

@C.oncreate
def spew(obj):
  obj.spew = 42
  return obj

c = C()
print c.spew
和开发者交流更多问题细节吧,去 写回答
相关文章
Python回调函数的实现
回调函数就是一个通过函数名调用的函数。如果你把函数的名字(地址)作为参数传递给另一个函数,当这个参数被用来调用其所指向的函数时,我们就说这是回调函数.
Python碎片公众号
2021/02/26
3.9K0
Python回调函数的实现
asp.net中回发或回调参数无效。在配置中使用 <pages enableEventValidation=”… 问题解决[通俗易懂]
回发或回调参数无效。在配置中使用 <pages enableEventValidation=”…
全栈程序员站长
2022/09/15
2K0
回调函数在Java中的应用
关于回调函数(Callback Function),维基百科已经给出了相当简洁精炼的释义。Java的面向对象模型不支持函数,其无法像C语言那样,直接将函数指针作为参数;尽管如此,我们依然可以基于接口来获得等效的回调体验。
程序猿杜小头
2022/12/01
3K0
PHP中on回调的实现(十六节)
各位好,我是老李。和老李一同完成《PHP网络编程》,虽然我知道实际上从头到尾可能只有我一个人在搞。我告诉你们一定要好好在家好好学习、远程工作,不要折腾地自己最后连班都没法上了,要好好学习、要不断学习、要终身学习。
老李秀
2020/02/19
1.5K0
回调函数原理与Python实现
回调函数的定义与普通函数并没有本质的区别,但一般不直接调用,而是作为参数传递给另一个函数,当另一个函数中触发了某个事件、满足了某个条件时就会自动调用回调函数。下面的代码用来删除可能会包含只读属性文件的文件夹,主要演示回调函数的原理和用法。 import os import stat def remove_readonly(func, path): #定义回调函数 os.chmod(path, stat.S_IWRITE) #删除文件的只读属性
Python小屋屋主
2018/04/16
1.7K0
java中如何实现"回调函数"
既然我们知道回调函数的用途是事件的响应,那么我们就从这里入手。 假设我们有这样一个场景,一家人坐在一起吃饭,但是我们中国的规矩是,长辈没动筷子,小辈们是不能动的,所以必须等着长辈动筷子这一事件完成之后,小辈们才能开始。 接下来我们就用回调函数来解决。由于java中没有指针一说,故而也没了*,但是java提供了 接口帮我们实现 回调函数,俗称 接口回调。
林老师带你学编程
2019/05/25
1.9K0
Python 回调函数实现异步处理
说到异步处理大家应该会联想到Ajax 处理,那我们先来说说什么是Ajax 请求。
Wu_Candy
2022/07/04
1.9K0
Python 回调函数实现异步处理
回发或回调参数无效。在配置中使用 <pages enableEventValidation=”true”/> 或在页面中使用 <%@ Page EnableEventValidation=”true”
回发或回调参数无效。在配置中使用 <pages enableEventValidation=”true”/> 或在页面中使用 <%@ Page EnableEventValidation=”true” %> 启用了事件验证。出于安全目的,此功能验证回发或回调事件的参数是否来源于最初呈现这些事件的服务器控件。如果数据有效并且是预期的,则使用 ClientScriptManager.RegisterForEventValidation 方法来注册回发或回调数据以进行验证。
全栈程序员站长
2022/09/15
1.7K0
IT文档中总出现的"hooks" 是什么? "钩子" ? 回调 ?
就像一些外来的钩子,在源代码之间钩取一些信息,当捕捉到感兴趣的事时,就拦截下来,让自己的代码执行一下,处理一下这个信息,然后再放出去继续之前的进程。 这样就可以在不用改变源代码的情况下,做一些别的事情,比方说监控、分析和一些恶意的事
JavaEdge
2020/05/27
1.4K0
IT文档中总出现的"hooks" 是什么? "钩子" ?  回调 ?
[Go] 利用函数类型实现封装中的回调
当进行业务逻辑开发的时候,经常要进行封装,封装成独立的类文件,在类文件的属性中预留出函数类型的API
唯一Chat
2019/12/19
2.4K0
如何实现RTMP或RTSP播放端回调YUV/RGB数据?
正好前些年我们做RTSP和RTMP直播播放的时候,实现过相关的需求,本文就以Android为例,大概说说具体实现吧。
音视频牛哥
2022/09/07
7950
enableEventValidation 回发或回调参数无效 的解决办法[通俗易懂]
回发或回调参数无效。在配置中使用 <pages enableEventValidation=”true”/> 或在页面中使用 <%@ Page EnableEventValidation=”true” %> 启用了事件验证。出于安全目的,此功能验证回发或回调事件的参数是否来源于最初呈现这些事件的服务器控件。如果数据有效并且是预期的,则使用 ClientScriptManager.RegisterForEventValidation 方法来注册回发或回调数据以进行验证。
全栈程序员站长
2022/09/15
2.2K0
使用委托实现同步回调与异步回调
使用委托可以执行的一项有用操作是实现回调。回调是传入函数的方法,在函数结束执行时调用该方法。 例如,有一个执行一系列数学操作的函数。在调用该函数时,也向其传递一个回调方法,从而在函数完成其计算工作时,调用回调方法,向用户通知计算结果。 同步回调    首先声明两个方法: AddTwoNumbers():接受两个整型实参以及一个类型委托 ResultCallback():接受一个字符串,并显示出来。代码如下: using System; using System.Collections.Generic
hbbliyong
2018/03/05
3.1K0
使用委托实现同步回调与异步回调
SystemVerilog中的callback(回调)
在第二次systemverilog实验中,我看到有同学用到了callback函数,今天就是简单讲讲这个方法。
数字IC小站
2020/06/30
2.6K0
实现java的异步回调
说下java的异步回调模式,是指当调用者实现了CallBack接口,调用者包含了被调用者的引用,在调用者类中调用被调用者的方法,然后在被调用者类的方法中调用调用者类的callBack方法。
码农王同学
2020/04/08
4.7K0
实现java的异步回调
JavaScript基础——回调(callback)是什么
上篇文章《JavaScript基础——你真的了解JavaScript吗?》,我们明白了JavaScript是一个单线程、非阻塞、异步、解释性语言,清楚了什么是单线程、进程、阻塞、调用堆栈、异步回调、任
前端达人
2018/12/02
1.6K0
JavaScript基础——回调(callback)是什么
java 中的异步回调
异步回调,本来在c#中是一件极为简单和优雅的事情,想不到在java的世界里,却如此烦琐,先看下类图: 先定义了一个CallBackTask,做为外层的面子工程,其主要工作为start 开始一个异步操作
菩提树下的杨过
2018/01/18
3.2K0
java 中的异步回调
javascript异步中的回调
我们之前介绍了javascript异步的相关内容,我们知道javascript以同步,单线程的方式执行主线程代码,将异步内容放入事件队列中,当主线程内容执行完毕就会立即循环事件队列,直到事件队列为空,当用产生用户交互事件(鼠标点击,点击键盘,滚动屏幕等待),会将事件插入事件队列中,然后继续执行。 处理异步逻辑最常用的方式是什么?没错这就是我们今天要说的---回调
陌上寒
2019/04/02
2.2K0
javascript异步中的回调
iOS中的「回调(callback)」
本文主要参考:《Object-C 编程 Big Nerd Ranch Guide》一书第24章
iOS Development
2019/02/14
3.5K0
点击加载更多

相似问题

在Java中实现常量的最佳方式是什么?

2927

离线语音识别回调中audioUrl参数的值是什么?

1333

短信回调地址,取不到回调的内容?

61.5K

填写正确的直播回调URL,没有回调?

1681

不进入addMessageUpdateListener回调是什么原因导致的?

0133
相关问答用户
腾讯云TDP | TDP会员擅长3个领域
到家集团 | 技术VP擅长5个领域
腾讯云TDP | KOL擅长5个领域
擅长4个领域
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文