【问题标题】:return a function object with parameter binded?返回绑定参数的函数对象?
【发布时间】:2011-05-01 19:31:11
【问题描述】:

全部,

def a(p):
    return p+1

def b(func, p):
    return func(p)

b(a,10)   # 11

这里我其实不想要结果“11”,我想要的是一个已经绑定参数的函数对象,我们将它命名为c。

当我使用 c() 或类似的东西时,它会给我结果 11,可能吗?

谢谢!

【问题讨论】:

    标签: python function object return


    【解决方案1】:

    functool 和返回函数对象都有效。我运行的一个小测试表明返回函数对象方法稍微快一些。

    import time
    import functools
    
    #####################################
    ## Returning function object method
    #####################################
    
    def make_partial(n):
        def inc(x):
            return x+n
        return inc
    
    start = time.clock()
    for i in range(10000):
        g = make_partial(i)
    print("time taken to create 10000: {}".format(time.clock() - start))
    
    b = 0
    
    start = time.clock()
    for i in range(10000):
        b += g(i)
    print("time taken to use it 10000 times: {}".format(time.clock() - start))
    
    
    #####################################
    ## Using functools method 
    #####################################
    
    def make_partial2(x,n):
        return x + n
    
    start = time.clock()
    for i in range(10000):
        g = functools.partial(make_partial2,i)
    print("time taken to create 10000: {}".format(time.clock() - start))
    
    b = 0
    
    start = time.clock()
    for i in range(10000):
        b += g(i)
    print("time taken to use it 10000 times: {}".format(time.clock() - start))
    

    导致:

    time taken to create 10000: 0.0038569999999999993
    time taken to use it 10000 times: 0.0030769999999999964
    time taken to create 10000: 0.004314000000000151
    time taken to use it 10000 times: 0.00390299999999999
    

    显示它的制作和调用都更快。 (虽然不多)

    【讨论】:

      【解决方案2】:

      functools 模块提供了partial 函数,它可以给你柯里化函数:

      import functools
      
      def a(p):
          return p+1
      
      def b(func, p):
          return functools.partial(func, p)
      
      c = b(a,10)
      print c() # >>  11
      

      它可以用来给函数应用一些参数,剩下的留给提供:

      def add(a,b):
          return a+b
      
      add2 = functools.partial(add, 2)
      print add2(10)  # >> 12
      

      【讨论】:

      • 你能解释一下为什么2和10可以分开吗?
      • functools.partial 接受一个函数和一些参数,然后返回一个接受其余参数的函数。
      • partial 不返回函数,而是返回一个部分对象,所以如果你想用 f 做 f(c) 期望一个会失败的函数!
      【解决方案3】:

      你也可以使用 functools 模块

      import functools def add(a,b): return a+b >> add(4,6) 10 >> plus7=functools.partial(add,7) >>plus7(9) 16

      【讨论】:

        【解决方案4】:

        您可以创建另一个函数,使用您想要的参数调用您的函数。

        def old_function(x,y):
            return x+y
        
        def bound_parameter_function(x):
            return old_function(x,10)
        

        当然,如果您需要即时创建此类函数,您可以编写另一个函数来为您完成这项工作:

        def parameter_bound(f, parm_to_bind):
            def ret(y):
                return f(parm_to_bind,y)
             return ret
        
        new_func=parameter_bound(old_function,10)
        new_func(1)
        

        【讨论】:

          【解决方案5】:

          虽然不确定用处,还是用lambda吧:

          >>> def a(p): return p+1
          ... 
          >>> def b(func, p):
          ...     g = lambda p: func(p) 
          ...     return g
          ... 
          >>> 
          >>> b(a, 4)
          <function <lambda> at 0x100430488>
          >>> k = b(a, 4)
          >>> k(5)
          6
          

          【讨论】:

            【解决方案6】:

            做到这一点的唯一方法是将其包装在 lambda 中:

            c = lambda : b(a,10)
            c() # 11
            

            虽然你还是要给它起名字,但与

            相比,这并不能真正为你买任何东西
            def c():
              b(a,10)
            

            【讨论】:

            • 谢谢,实际上我会有一个 b(a,x) 的列表,我想使用 [x() for x in list] 来获得结果。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-23
            相关资源
            最近更新 更多