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

ffvjumwh  于 2023-01-01  发布在  Python
关注(0)|答案(7)|浏览(187)

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

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中使用之前不被调用呢?

bxjv4tth

bxjv4tth1#

在这个代码中

if callback != None:
    callback

callback本身不做任何事情;它接受参数-def callback(a, b):
您先执行callback(1, 2)的事实将调用该函数,从而打印Sum = 3,然后使用callback函数的结果调用main(),该函数打印第二行
由于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)
mwecs4sa

mwecs4sa2#

以下是您想要执行的操作:

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)
nr7wwzry

nr7wwzry3#

问题是在将回调函数作为可调用函数传递之前,需要先对它进行求值。解决这个问题的一个灵活方法是:

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)

您也可以选择包含一种支持关键字参数的方法。

suzh9iv8

suzh9iv84#

正如注解中提到的,只要回调函数的后缀带有开括号和闭括号,就会调用回调函数;所以你经过的时候就叫它。
您可能希望使用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)
elcex8rz

elcex8rz5#

您的代码按如下方式执行:

main(callback(1, 2))

使用(1, 2)调用callback函数,并返回None(如果没有return语句,您的函数将打印Sum = 3并返回None
使用None作为参数调用main函数(因此callback != None将始终为False

izj3ouym

izj3ouym6#

这是一篇老文章,但下面的内容可能是对编写和使用回调函数的补充说明,特别是如果你想知道它从哪里获得参数,以及你是否可以访问它的返回值(如果没有办法从接收回调函数的函数获得返回值)。
下面的代码定义了一个类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中的参数foo_value获取的,在main中被赋予了值20,而c_value1是从foo内部获取的,在本例中是值10(如果foo是第三方导入模块的某个方法,如pyaudio,则可能无法清楚地看到)。
回调函数function的返回值可以通过将其添加到类CallBack的命名空间(在本例中为cls.operator)来检索

xvw2m8pv

xvw2m8pv7#

您可以使用匿名函数

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)

相关问题