如何编写简单的回调函数?

时间:2016-11-28 11:18:39

标签: python callback

Python 2.7.10

我编写了以下代码来测试一个简单的回调函数。

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.

为什么Add any two digitsSum = 3之后?我想这是因为回调函数首先执行。如何执行main()中的所有其他代码后执行回调函数?

6 个答案:

答案 0 :(得分:26)

callback本身并没有做任何事情。它接受参数。

您首先执行callback(1, 2)这一事实将调用该函数,从而打印Sum = 3

由于callback没有返回显式值,因此返回None,因此您的代码等同于

callback(1, 2)
main()

您可以尝试不首先调用该函数并仅传递其句柄。

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

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

main(1, 2, callback)

答案 1 :(得分:3)

正如评论中所提到的,只要后缀为开放和关闭的parens,就会调用你的回调函数;因此,当你通过它时会调用它。

您可能想要使用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 :(得分:2)

这是你想做的事情:

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

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

main(1, 2, callback)

答案 3 :(得分:0)

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

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 != None:
        callback(*cargs)

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

或者,您可能希望包含一种支持关键字参数的方法。

答案 4 :(得分:0)

您的代码执行如下:

main(callback(1, 2))
使用callback调用

(1, 2)函数并返回None(如果没有return语句,您的函数将打印Sum = 3并返回None

使用main作为参数调用

None函数(因此callback != None始终为False

答案 5 :(得分:0)

这是一个古老的文章,但是也许以下可能是关于编写和使用回调函数的更多说明,尤其是如果您想知道它从何处获取其参数以及是否可以访问其返回值(如果无法从带有回调函数的函数中获取它。)

以下代码定义了一个类CallBack,该类具有两个回调方法(函数)my_callback_summy_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,而{{1} }在这种情况下,它是从c_value1内部获取的值10(如果foo是第三方导入模块的某种方法(例如pyaudio),则可能看不到)。

可以通过将回调函数的返回值添加到类foo的命名空间(在本例中为CallBack

中)来检索