【问题标题】:Can someone explain to me the difference between a Function Object and a Closure有人可以向我解释一下函数对象和闭包之间的区别吗
【发布时间】:2013-07-09 04:41:03
【问题描述】:

“函数对象”是指类的对象,它在某种意义上是可调用的,并且可以在语言中作为函数处理。例如在python中:

class FunctionFactory:
    def __init__ (self, function_state):
        self.function_state = function_state
    def __call__ (self):
        self.function_state += 1
        return self.function_state

>>>> function = FunctionFactory (5)
>>>> function ()
6
>>>> function ()
7

我的问题是 - FunctionFactory 和函数的这种使用会被视为闭包吗?

【问题讨论】:

    标签: python function functional-programming closures


    【解决方案1】:

    闭包是一段代码,它在定义它的环境中关闭,捕获它的变量。在大多数现代语言中,函数都是闭包,但不一定如此,您可以想象闭包不是函数对象(例如 Ruby 块,它们根本不是对象)。

    这是一个闭包的基本测试:

    def bar():
        x = 1
        def foo():
            print x
        return foo
    
    x = 2
    bar()()
    

    如果它打印 1,则 foo 是一个闭包。如果打印 2,则不是。

    【讨论】:

      【解决方案2】:

      ... FunctionFactory 和函数的这种使用会被视为闭包吗?

      本身不是,因为它不涉及范围。虽然它确实模仿了闭包的功能。

      def ClosureFactory(val):
        value = val
        def closure():
          nonlocal value # 3.x only; use a mutable object in 2.x instead
          value += 1
          return value
        return closure
      
      3>> closure = ClosureFactory(5)
      3>> closure()
      6
      3>> closure()
      7
      

      【讨论】:

        【解决方案3】:

        闭包是一个函数,它会记住定义它的环境并可以访问周围范围内的变量。函数对象是可以像函数一样调用的对象,但它实际上可能不是函数。函数对象不是闭包:

        class FunctionObject(object):
            def __call__(self):
                return foo
        
        def f():
            foo = 3
            FunctionObject()() # raises UnboundLocalError
        

        FunctionObject 无权访问创建它的范围。但是,函数对象的__call__ 方法可能是一个闭包:

        def f():
            foo = 3
            class FunctionObject(object):
                def __call__(self):
                    return foo
            return FunctionObject()
        print f()() # prints 3, since __call__ has access to the scope where it was defined,
                    # though it doesn't have access to the scope where the FunctionObject
                    # was created
        

        【讨论】:

        • 最后的打印语句应该是:print f()() 顺便说一句很好的解释。
        猜你喜欢
        • 2013-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        • 2023-04-08
        • 2016-10-10
        • 2019-05-14
        • 1970-01-01
        相关资源
        最近更新 更多