如何编写一个简单的回调函数? [重复]

问题描述 投票:0回答:7

我有这个示例代码,试图使用回调函数进行演示:

def callback(a, b):
    print('Sum = {0}'.format(a+b))

def main(callback=None):
    print('Add any two digits.')
    if callback != None:
        callback

main(callback(1, 2))

我得到这个结果:

Sum = 3
Add any two digits.

看来回调函数先于

main
中的逻辑执行。为什么?我怎样才能让它在
main
内使用之前不调用回调?

python callback
7个回答
61
投票

在这段代码中

if callback != None:
    callback

callback
本身什么都不做;它接受参数 -
def callback(a, b):

您首先执行

callback(1, 2)
的事实将调用该函数,从而打印
Sum = 3
,然后
main()
被调用,带有
callback
函数的结果,即打印第二行

由于

callback
没有返回明确的值,它被返回为
None
.

因此,您的代码等同于

callback(1, 2)
main()

解决方案

你可以尝试先不调用函数,只传递它的句柄。

def callback(n):
    print("Sum = {}".format(n))

def main(a, b, _callback = None):
    print("adding {} + {}".format(a, b))
    if _callback:
        _callback(a+b)

main(1, 2, callback)

10
投票

这是你想做的:

def callback(a, b):
    print('Sum = {0}'.format(a+b))

def main(a,b,f=None):
    print('Add any two digits.')
    if f is not None:
        f(a,b)

main(1, 2, callback)

5
投票

问题是您在将回调作为可调用对象传递之前正在评估回调。解决问题的一种灵活方法是:

def callback1(a, b):
    print('Sum = {0}'.format(a+b))

def callback2(a):
    print('Square = {0}'.format(a**2))

def callback3():
    print('Hello, world!')

def main(callback=None, cargs=()):
    print('Calling callback.')
    if callback is not None:
        callback(*cargs)

main(callback1, cargs=(1, 2))
main(callback2, cargs=(2,))
main(callback3)

您可能希望包括一种支持关键字参数的方法。


4
投票

如评论中所述,只要回调以打开和关闭的括号为后缀,就会调用它;因此当你通过它时它被称为。

您可能想使用 lambda 并传入值。

#!/usr/bin/env python3

def main(callback=None, x=None, y=None):
    print('Add any two digits.')
    if callback != None and x != None and y != None:
        print("Result of callback is {0}".format(callback(x,y)))
    else:
        print("Missing values...")

if __name__ == "__main__":
    main(lambda x, y: x+y, 1, 2)

2
投票

你的代码执行如下:

main(callback(1, 2))

callback
函数用
(1, 2)
调用并返回
None
(没有return语句,你的函数打印
Sum = 3
并返回
None

main
函数以
None
作为参数调用(因此
callback != None
将始终为
False


1
投票

这是一篇旧帖子,但也许以下内容可能是关于编写和使用回调函数的额外说明,特别是如果您想知道它从哪里获取参数以及是否可以访问其返回值(如果无法获取它)来自采用回调函数的函数)。

下面的代码定义了一个类

CallBack
,它有两个回调方法(函数)
my_callback_sum
my_callback_multiply
。回调方法被送入方法
foo
.

# understanding callback

class CallBack:

    @classmethod
    def my_callback_sum(cls, c_value1, c_value2):
        value = c_value1 + c_value2
        print(f'in my_callback_sum --> {c_value1} + {c_value2} = {value}')
        cls.operator = '+'
        return cls.operator, value

    @classmethod
    def my_callback_multiply(cls, c_value1, c_value2):
        value = c_value1 * c_value2
        print(f'in my_callback_multiply --> {c_value1} * {c_value2} = {value}')
        cls.operator = '*'
        return cls.operator, value

    @staticmethod
    def foo(foo_value, callback):
        _, value = callback(10, foo_value)
        # note foo only returns the value not the operator from callback!
        return value


if __name__ == '__main__':
    cb = CallBack()

    value = cb.foo(20, cb.my_callback_sum)
    print(f'in main --> {value} and the operator is {cb.operator}')

    value = cb.foo(20, cb.my_callback_multiply)
    print(f'in main --> {value} and the operator is {cb.operator}')

结果:

in my_callback_sum --> 10 + 20 = 30
in main --> 30 and the operator is +
in my_callback_multiply --> 10 * 20 = 200 
in main --> 200 and the operator is *

你可以看到回调函数的一个值

c_value2
它从
foo_value
中的参数
foo
获得并在
main
中给出值20,而
c_value1
它从内部获得
foo
在这种情况下值 10(如果
foo
是第三方导入模块的某种方法,如 pyaudio,则可能不清晰可见)。

回调函数函数的返回值可以通过将其添加到类的命名空间中来检索

CallBack
,在本例中为
cls.operator


0
投票

可以使用匿名函数

def callback(a, b):
    print('Sum = {0}'.format(a+b))

def main(callback=None):
    print('Add any two digits.')
    if callback is not None:
        callback()

tmp_func = lambda: main(lambda: callback(2,3))
tmp_func()

#OR

tmp_func = lambda x,y: main(lambda: callback(x,y))
tmp_func(2,4)
© www.soinside.com 2019 - 2024. All rights reserved.