【问题标题】:How to write a simple callback function?如何写一个简单的回调函数?
【发布时间】:2017-04-12 02:25:07
【问题描述】:

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()中的所有其他代码执行完毕后,如何执行回调函数?

【问题讨论】:

标签: python python-2.7 callback python-2.x


【解决方案1】:

在这段代码中

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)

【讨论】:

  • 在回调之前传递两个 args 让解释器为你做一些工作是个好主意!
  • @erip 你是什么意思?喜欢你的答案吗?
  • 我的意思是你的想法是个好主意。 :) 强制用户在回调之前传递参数可确保它们存在,以免调用main 时出错。
  • @cricket_007,回调方法只是将可调用对象传递给函数或类以稍后调用它,对吗?
  • @nad87563 如果函数句柄已经定义(is not None
【解决方案2】:

这是你想做的:

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)

【讨论】:

    【解决方案3】:

    正如在 cmets 中提到的,只要以 open 和 close 括号为后缀,就会调用您的回调;因此,当您通过它时会调用它。

    您可能想要使用 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)
    

    【讨论】:

      【解决方案4】:

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

      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)
      

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

      【讨论】:

        【解决方案5】:

        你的代码执行如下:

        main(callback(1, 2))
        

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

        main 函数以None 作为参数调用(所以callback != None 将永远是False

        【讨论】:

          【解决方案6】:

          这是一篇旧文章,但也许​​以下内容可能是关于编写和使用回调函数的额外说明,特别是如果您想知道它从哪里获取参数以及您是否可以访问它的返回值(如果没有办法从接受回调函数的函数中获取)。

          下面的代码定义了一个类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,则可能不清晰可见)。

          回调函数函数的返回值可以通过添加到类CallBack的命名空间中获取,本例中为cls.operator

          【讨论】:

          • 这似乎不是一个回调函数,因为它不会“回调”类外部定义的函数。对我来说,这是一个引用函数......抽象技术很好,但从技术上讲不是回调,IMO。
          【解决方案7】:

          你可以使用匿名函数

          def callback(a, b):
              print('Sum = {0}'.format(a+b))
          
          def main(callback=None):
              print('Add any two digits.')
              if callback != 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)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-04-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-31
            • 1970-01-01
            相关资源
            最近更新 更多