【问题标题】:How are functions within functions handled?函数中的函数如何处理?
【发布时间】:2019-07-14 10:44:12
【问题描述】:

我试图了解 Python 如何处理以下示例中的代码:

cake()()被执行时,Python首先打印'beets'然后打印'sweets'

但是,当 chocolate() 被执行时,Python 只打印 'sweets'

有人可以解释这两种情况的区别吗?

另外,当more_chocolate 被执行时,Python 不会打印任何值,它只是返回'cake'。

我相信对于这些情况有一个简洁的解释。希望有人能解释一下!

def cake():
    print('beets')
    def pie():
        print('sweets')
        return 'cake'
    return pie

chocolate = cake()

cake()()

chocolate()

more_chocolate, more_cake = chocolate(), cake

more_chocolate

【问题讨论】:

  • chocolate = cake() 之后(也打印beets)你有chocolate = pie 所以当你使用chocolate() 然后你运行pie() 它只能打印sweets
  • print('beets')def pie()之间的额外缩进是什么意思?它会在当前编写时产生语法错误
  • cake()() 像另外两行 chocolate = cake()chocolate() 一样工作
  • 我现在明白了。谢谢!

标签: python lambda test-environments


【解决方案1】:
chocolate = cake()

这将标识符chocolate 绑定到调用cake 返回的对象- 它返回一个函数对象- 因此,巧克力绑定到该函数对象(chocolate 绑定到函数对象pie)。 调用cake 的副作用是打印了“甜菜”。

cake()()

这会调用cake,它会返回一个函数对象。这次函数对象没有绑定名称。返回后,我们调用匿名函数对象。结果是“甜菜”从对cake 的调用中打印出来,而“sweets”从对pie 的调用中打印出来。 pie 也返回字符串“cake”,但该字符串未绑定或捕获。

chocolate()

chocolate 仍然绑定到 cake 返回的函数对象,当我们执行 chocolate = cake() 时。现在我们只是调用我们之前捕获的函数对象。由于我们现在实际上并没有调用cake(我们只调用pie),因此不会打印“beets”,但会打印“sweets”。同样,这将返回字符串“cake”,但同样,它没有被绑定或捕获。

more_chocolate, more_cake = chocolate(), cake

这将more_chocolate 绑定到调用chocolate 返回的对象(即字符串“cake”)。它还将more_cake 绑定到cake。不确定您是否真的打算这样做 - 所做的只是将 more_cake 绑定到 cake 绑定到的同一个函数对象,但您实际上并没有在这里调用任何函数。

【讨论】:

    【解决方案2】:

    当您执行cake() 时,会运行以下块:

    print('beets')
    def pie():
        print('sweets')
        return 'cake'
    return pie
    

    原来如此:

    • 打印beets
    • 执行pie函数定义,函数体尚未运行,因此没有打印sweets
    • 返回pie函数对象

    您将返回的函数对象保存为名称chocolate,因此它现在引用pie 函数对象。

    所以当你执行chocolate() 时,它实际上现在运行pie() 并执行以下操作:

    • 打印sweets
    • 返回字符串cake

    当您执行cake()() 时,它也会执行相同的操作,而无需使用中间变量chocolate。所以cake()() 运行从cake() 返回的函数对象,即带有打印的pie

    【讨论】:

      【解决方案3】:

      这个概念被称为Currying Function。在函数式编程中,柯里化是将多参数函数简化为具有单个参数的更简单函数的方法。

      要了解您的示例的行为,让我们将其分解:

      def cake():
          print('beets')
          def pie():
              print('sweets')
              return 'cake'
          return pie
      

      这里我们有一个函数 cake,它将打印 beets 并返回一个函数 pie。

      现在如果我们使用:

      cake()()
      

      这里我们调用了它两次,第一次当cake() 将被执行时,它会打印 beets 并返回 pie 函数,由于第二个集合,它会立即被调用() 个结果打印 sweets

      如果我们执行它:

      chocolate = cake()
      

      我们只执行了一次,所以它会打印 beets 并且返回的 pie 函数将被设置到变量 chocolate 中。

      然后当我们调用巧克力时,它会打印 sweets 并且它会返回一个字符串 cake。您在以后的情况下将其保存在 more_chocolate 变量中。由于它只是一个字符串文字并且不打印任何内容,因此输出上没有打印任何内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-29
        • 2014-01-07
        相关资源
        最近更新 更多