关于Asterisk ARI Python示例中Lambda作为回调的疑问
Asterisk ARI Python回调:Lambda vs 直接传函数的区别
直接传函数的前提:参数完全匹配
outgoing.on_event('StasisStart', outgoing_on_start)这种写法能成立,是因为outgoing_on_start的参数定义和ARI触发StasisStart事件时传递的参数完全对应。ARI在触发该事件时,会自动把事件对象、通道对象等参数传给回调函数,而outgoing_on_start的写法大概是这样的:
def outgoing_on_start(event, channel): # 处理StasisStart事件的逻辑
这种情况下直接传函数名就行,ARI会自动帮你把对应参数传进去。
用Lambda的核心原因:参数不匹配+需要绑定外部变量
incoming.on_event('StasisEnd', lambda *args: safe_hangup(outgoing))里用lambda,本质是解决两个问题:
- 参数不匹配:ARI触发
StasisEnd时会传递事件相关的参数,但safe_hangup根本不需要这些,它需要的是outgoing这个通道对象。如果直接传safe_hangup,ARI会把事件参数塞给它,直接导致参数错误。 - 绑定外部变量:我们需要把
outgoing这个外部的通道对象传给safe_hangup,但ARI的回调机制只会传事件自带的参数,没法额外传我们需要的变量。lambda在这里相当于一个“中间层”,先接收ARI传来的所有参数(用*args忽略),再调用safe_hangup并传入outgoing。
为什么不能直接调用safe_hangup?
要是你写成incoming.on_event('StasisEnd', safe_hangup(outgoing)),这不是把函数当回调传,而是立刻执行了safe_hangup(outgoing),然后把它的返回值(一般是None)传给on_event。这就完全错了——我们要的是StasisEnd事件触发时才执行挂断操作,而不是程序一开始就把电话挂了。
lambda是个匿名函数,传进去的是函数本身,只有当事件触发时才会执行lambda,进而调用safe_hangup(outgoing),这才符合回调的逻辑。
内容的提问来源于stack exchange,提问作者Amir
相关产品推荐
相关产品推荐

