【问题标题】:Why does foo = function() run the function in Python?为什么 foo = function() 在 Python 中运行函数?
【发布时间】:2012-03-11 14:22:01
【问题描述】:

我已经完成了 Learn Python the Hard Way 中的练习 41,我很难理解这样一个事实,即整个事情取决于一个正在运行的函数,因为它被分配为一个值一个变量。我写了一个小脚本来确认它是如何工作的,并且确实如此:

def pants():
    print "Put on some pants!"

def shorts():
    print "And don't forget your underwear!"

zap = pants()
thing = shorts()

结果是:

Put on some pants!
And don't forget your underwear! 

很明显这会发生,但我不明白为什么这种语言会这样工作——语言背后的逻辑是什么,使它成为一种有价值的操作方式。我认为这对我理解为什么会有所帮助,而不仅仅是“它就是这样工作的”。

为了清楚起见:我在问(我猜)为什么函数正在运行,而我所做的只是将它分配为某物的值。打印语句就在那里,所以我可以看到该函数确实正在运行。

事实上我从来没有真正跑步过

裤子() 短裤()

这让我很困惑。

打个比喻,如果我在家烘焙饼干是“cookies()”,而我要在星期六做饼干,我最终可能会相信

星期六 = 饼干()

但只是想“嘿,星期六是饼干日”与 实际上烘烤饼干不一样......那为什么只是说

星期六 = cookies()

实际上是烘烤饼干,而不是仅仅使用变量“cookies()”设置星期六以供以后使用?

【问题讨论】:

  • 您可能将printreturn 混淆了。
  • 我认为 Juhana 可能是对的。您是否期望zap 具有“穿上裤子!”的价值?如果是这样,则在分配后将 print 更改为 returnprint zap
  • 是的,显然您的期望与语言不一致。你期待什么?
  • 什么是更直观的工作方式?
  • 您是在问为什么要调用这些函数,或者为什么要在屏幕上显示输出?请澄清。

标签: python function variables


【解决方案1】:

当您使用括号 () 时,函数会被调用。如果您想将函数分配给变量以重复使用它,您应该删除那里的括号。

例子:

def pants():
    print "Put on some pants!"

def shorts():
    print "And don't forget your underwear!"

zap = pants
thing = shorts

然后当你想调用这些函数时:

zap()
thing()

【讨论】:

  • 那么 () 的存在将事物“转换”为 Python 眼中的函数,而 Python 试图立即运行这些函数以获取它们的返回值?
  • 不,将它们“转换”为函数是在您声明它们时。在 Python 中,一切都是对象。函数是一个“可调用”对象。作为一个对象,您可以将其分配给一个变量,将其作为属性分配给另一个对象,将其作为参数传递等等。然后当您调用它时,它会执行它的过程。有关更多详细信息,我建议您阅读 Python 的 data model
  • 添加到我之前的评论:() 的存在告诉 Python 调用该对象。如果它是一个函数,它将被执行,如果不是,它将引发一个异常,指出该对象不可调用。该函数是否返回某些内容取决于您以及您需要做什么。如果要将函数的结果分配给变量,则需要使用 return ,正如其他答案中所指出的那样。如果你只是想打印一些东西,你可以使用print,不需要返回任何东西。
【解决方案2】:

很明显这会发生,但我不明白为什么这种语言会这样工作——语言背后的逻辑是什么,使它成为一种有价值的操作方式。我认为这有助于我理解为什么会这样,而不仅仅是“它就是这样工作的”。

语言需要某种方式来区分函数和调用函数的行为。这就是括号提供的内容。

f = foo

现在f 绑定到函数本身。函数foo可以被f()执行。

f = foo()

这会调用函数foo并将返回值绑定到f

请注意,是否将返回值绑定到名称是无关紧要的。简单写

foo()

也将执行该函数,但返回值将被忽略。

【讨论】:

  • 因此,如果我的理解正确,Python 将尝试在它之后作为函数执行任何带有 () 的内容,而不管其所处的大多数上下文 - 使用函数的返回值代替function() 如果该函数是应该代表其当前上下文中的变量的东西?
【解决方案3】:

虽然看起来您的函数没有返回任何内容,但实际上它们确实返回了。引用the Python.org documentation:

return 语句从函数返回值。没有表达式参数的返回返回无。离开函数的末尾也返回 None。

所以你的函数看起来像这样:

def pants():
    print "Put on some pants!"
    return None

def shorts():
    print "And don't forget your underwear!"
    return None

无论pants 返回什么(即pants() 的值),你的任务分配给zap,无论shorts 返回什么,分配给thing。在您的情况下,两者都是None,但当然必须运行这些函数才能解决这个问题(*)。毕竟,pants 可能会在闰年返回 42,而shorts 在某些随机数生成器“滚动”为 6 时返回 'Foobar'


(*) 题外话:“必须运行”的功能不应被认为是普遍正确的。在 pure setting 中,抛开 Python 的细节(我对此知之甚少),编译器可能会意识到这两个函数是相同的 None,并导致在程序运行时不会进行任何调用。但是打印某些东西(或检查当前年份是否是闰年或掷骰子)的函数不会是纯函数。

【讨论】:

    【解决方案4】:

    zap = pants()会将函数的返回值绑定到变量,所以如果绑定到变量,函数当然会运行。

    def foo():
        return 1
    
    var = foo()
    print var
    

    将打印1

    我希望这会有所帮助。

    编辑:如果您希望变量的值是“穿上一些裤子”,那么您确实会混淆 printreturn,正如人们在 cmets 中指出的那样。

    【讨论】:

      【解决方案5】:

      当解释器看到函数名后跟 () 时,它就知道它应该执行该函数。

      你在那里做的是说“将这些函数的结果分配给这些变量”。

      但是由于您没有从这些函数返回任何值,因此您看不到变量中的任何内容。

      但是,由于您在其中有一个打印语句,您会看到解释器在尝试将变量分配给该函数的结果时执行这些函数。

      【讨论】:

        【解决方案6】:

        由于名称后面的括号,您的函数被调用:

        zap = pants()
        

        这会调用函数pant 并将结果放入zap。如果你这样做了:

        zap = pants
        

        那么 zap 现在将引用裤子函数本身。

        如果你只是写了

        pants()
        

        那么pants 函数也会被调用,但结果(即None)永远不会被放入变量中。

        【讨论】:

          【解决方案7】:

          根据您的问题,我认为您想要的 zap 将具有 "Put on some pants!" 的值,thing 将具有 "And don't forget your underwear!" 的值。如果这是你的问题,让我们讨论一下。否则,您无需进一步阅读,因为我刚刚讨论了所有这些内容。

          让我们让它变得有趣。当你定义一个函数时,你就像在创建一台机器,它可以做你想做的事情。现在让我们想象一台机器,当你给它一些食物时,它会切碎它们,然后……什么都不做!我的意思是我做了那台机器来切食物,别无其他!你不会拿回你切碎的食物,但它确实在你做的时候切碎了你的食物。

          现在,当您想要取回切碎的食物时,您可以创建另一台机器来获取您的食物,切碎并返回给您。硕果累累的机器,不是吗? ;-)

          它们对于编程或数学中的函数都是正确的(尽管我不知道数学中的任何 void 函数!:P)。在创建函数时,您必须告诉它是做了一些工作,还是做了一些工作并返回了结果。告诉函数的方法是return 语句。在你的函数中,你刚刚告诉做某事。那是print "......",功能也是如此。您最后调用 with () 并完成他们的工作,他们将其打印出来。但正如我所说,如果你不告诉它返回结果,它就不会。而且因为它没有返回任何结果,所以不会为变量分配任何内容(不要将他与None 混淆)。当您编写这些行(如果在解释器中)或运行脚本时,您将看到这些行已打印,但您的 zapthing 没有值。

          那么如何解决呢?告诉他们将这些行返回给变量。要告诉函数这样做,请将 print 语句替换为 return 语句。别介意去试验你所知道的,去了解你所知道的关于你的知识是真实的:-)

          希望对你有帮助:-)

          【讨论】:

            猜你喜欢
            • 2015-03-08
            • 2015-05-06
            • 2017-04-27
            • 2011-04-01
            • 1970-01-01
            • 2014-12-18
            • 2014-11-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多