简体   繁体   English

为什么foo = function()在Python中运行该函数?

[英]Why does foo = function() run the function in Python?

I'm up to Exercise 41 in Learn Python the Hard Way, and I'm having a really hard time wrapping my brain around the fact that the entire thing hinges on a function running just because it's been assigned as a value to a variable. 我要学习“难学Python”中的练习41,我真的很难全神贯注于整个事情取决于一个正在运行的函数,因为它只是作为一个值分配给变量的。 I wrote up a little script to confirm that this is how it works, and it does: 我写了一个小脚本来确认它是如何工作的,并且可以做到:

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

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

zap = pants()
thing = shorts()

With the results being: 结果为:

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

So obviously this happens, but I can't understand why the language works that way -- what the logic is behind the language that makes this a valuable way of operating. 很明显,这确实发生了,但是我不明白为什么语言会这样工作-语言背后的逻辑是什么使得这成为一种有价值的操作方式。 I think it'd be helpful for me moving forward to understand why this is, rather than just "that's the way it works." 我觉得这是我前进明白这是为什么 ,而不是仅仅有帮助的“这是它的工作方式。”

For clarity: I'm asking (I guess) why the function is running, when all I'm doing is assigning it as a value for something. 为了清楚起见:我在问(我猜)为什么函数运行,当我正在做的就是将其分配为某个值。 The print statements are just there so I can see that the function is indeed running. 打印语句就在那里,因此我可以看到该函数确实正在运行。

It's the fact that I'm not ever actually running 这是我从未真正跑步的事实

pants() shorts() 裤子()短裤()

that is confusing me. 这让我感到困惑。

To create a tortured analogy, if me-baking-cookies-at-home were "cookies()", and I were to make cookies on Saturdays, I might eventually believe that 为了创建一个折磨的类比,如果我在家烘烤cookie是“ cookies()”,而我要在星期六制作cookie,我可能最终会相信

Saturday = cookies() 星期六= Cookies()

but just thinking "hey, Saturday is cookie day" is not the same as actually baking cookies ... so why does just saying 但是只是在想“嘿,星期六是饼干日”与实际烘焙饼干不一样...所以为什么只说

Saturday = cookies() 星期六= Cookies()

actually bake the cookies, rather than just setting up Saturday with the variable "cookies()" for some later use? 实际烘烤cookie,而不仅仅是使用变量“ cookies()”在星期六设置以便以后使用?

When you use the parentheses () the function gets called. 使用括号()会调用该函数。 If you want to assign the function to the variable to reuse it you should remove there parentheses. 如果要将函数分配给变量以重用它,则应在其中删除括号。

Example: 例:

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

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

zap = pants
thing = shorts

And then when you want to call those functions: 然后,当您要调用这些函数时:

zap()
thing()

So obviously this happens, but I can't understand why the language works that way -- what the logic is behind the language that makes this a valuable way of operating. 很明显,这确实发生了,但是我不明白为什么语言会这样工作-语言背后的逻辑是什么使得这成为一种有价值的操作方式。 I think it'd be helpful for me moving forward to understand why this is, rather than just "that's the way it works." 我认为,这对我前进是有帮助的,而不仅仅是“这就是它的工作方式”。

The language needs some way to distinguish between the function and the act of calling the function. 语言需要某种方式来区分功能和调用功能的行为。 That is what the parentheses provide. 这就是括号所提供的。

f = foo

Now f is bound to the function itself. 现在f绑定到函数本身。 The function foo could be executed by f() . foo函数可以由f()执行。

f = foo()

This calls the function foo and binds the return value to f . 这将调用函数foo并将返回值绑定到f

Note that whether or not you bind the return value to a name is irrelevant. 请注意,是否将返回值绑定到名称无关紧要。 Simply writing 简单地写

foo()

will also execute the function but the return value will simply be ignored. 也会执行该函数,但是返回值将被忽略。

Although it may seem like your functions don't return anything, they do in fact. 尽管函数似乎不返回任何内容,但实际上它们确实返回任何内容。 Quoting the Python.org documentation : 引用Python.org文档

The return statement returns with a value from a function. return语句从函数返回值。 return without an expression argument returns None. 不带表达式参数的return返回None。 Falling off the end of a function also returns None. 从函数末尾掉落也会返回None。

So your functions really look like this: 因此,您的功能确实如下所示:

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

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

Your assignments assign to zap whatever pants returns (ie the value of pants() ), and to thing whatever shorts returns. 您的分配将分配给zap任何pants返回(即pants()的值),分配给任何shorts返回的thing In your case, both are None , but of course the functions must be run in order to figure this out(*). 在您的情况下,两者均为None ,但是当然必须运行函数才能弄清楚这一点(*)。 Afterall, it could be that pants returns 42 during leap years, and that shorts returns 'Foobar' whenever some random number generator "rolls" a 6. 毕竟,可能是pants在leap年返回42shorts在某些随机数生成器“滚动” 6时返回'Foobar'


(*) Digression: That the functions "must be run" should not be considered universally true. (*)离题:“必须运行”功能不应被普遍认为是正确的。 In a pure setting , and leaving aside the specifics of Python (of which I know very little), a compiler might realize that both functions are identically None , and cause no calls to be made when the program is run. 纯设置中 ,撇开Python的细节(我了解的很少),编译器可能会意识到两个函数完全相同None ,并且在程序运行时不进行任何调用。 But a function that prints something (or inspects whether the current year is a leap year, or rolls a die) won't be pure. 但是,打印某些内容(或检查当前年份是否为a年或掷骰子)的函数将不是纯函数。

zap = pants() will bind the return value of the function to the variable, so of course the function is run if you bind it to a variable. zap = pants()会将函数的返回值绑定到变量,因此,如果将函数绑定到变量,则当然可以运行该函数。

def foo():
    return 1

var = foo()
print var

will print 1 . 将打印1

I hope this helps. 我希望这有帮助。

Edit: If you expect the value of the variable to be "put on some pants", you are indeed confusing print and return , as people pointed out in the comments. 编辑:如果您希望变量的值是“穿上某些裤子”,那么您确实会混淆printreturn ,正如人们在评论中指出的那样。

When the interpreter sees a function name followed by () it knows that it's supposed to execute that function. 当解释器看到函数名称后跟()时,它知道应该执行该函数。

What you're doing there is saying "assign the result of these functions to these variables". 您在这里说的是“将这些函数的结果分配给这些变量”。

But since you are not returning any values from those functions, you're not seeing anything in the variables. 但是,由于您没有从这些函数返回任何值,因此您在变量中看不到任何内容。

However because you have a print statement in there, you are seeing the interpreter execute those functions as it attempts to assign the variable to results of that function. 但是,由于其中有一个print语句,因此您会看到解释器在尝试将变量分配给该函数的结果时执行这些函数。

Your functions are called because of the parenthesis after the name: 由于名称后有括号,因此会调用您的函数:

zap = pants()

This calls the function pants and puts the result in zap. 这将调用函数裤子并将结果放入zap中。 If you had done this instead: 如果您这样做,则:

zap = pants

then zap would now refer to the pants function itself. 那么zap现在将引用裤子功能本身。

And if you just wrote 如果你只是写

pants()

then the pants function would also get called, but the result (which is None) would never have been put in a variable. 然后将调用裤子函数,但结果(无)将永远不会放入变量中。

From your question what I think you want zap will have the value "Put on some pants!" 从您的问题中,我认为您想要的zap值将为"Put on some pants!" and thing will have the value "And don't forget your underwear!" thing的价值就是"And don't forget your underwear!" . If that is your problem let's discuss it. 如果这是您的问题,让我们讨论一下。 Otherwise you do not need to read further as I just discussed about all that. 否则,您不必阅读我刚刚讨论的所有内容。

Let's make it some fun. 让它变得有趣。 When you define a function, you are like creating a machine that does what you want it to do. 定义函数时,就像创建一台可以完成其功能的机器一样。 Now let's think of a machine that when you give some food in it, it chops them and ... does nothing! 现在,让我们想到一台机器,当您在其中放一些食物时,它会剁碎它们,而...什么也不做! I mean I made that machine to chop foods and nothing else! 我的意思是说我是用那台机器剁碎食物的! You won't get your chopped food back, but indeed it chopped your food as you made it for. 您不会拿回切碎的食物,但实际上它是将您切碎的食物切碎的。

Now, as you want your chopped food back, you create another machine that takes your food, chops them and return them to you. 现在,当您要切碎的食物时,您可以创建另一台可以将食物切碎的机器,然后将其切碎并还给您。 Fruitful machine, isn't it? 机器硕果累累,不是吗? ;-) ;-)

They are all true for functions in programming or math (though I don't know any void function in math! :P). 它们对于编程或数学函数都是正确的(尽管我不知道数学中有空函数!:P)。 When you are creating the function, you have to tell it whether it just does some work or it does some work and return the result . 创建函数时,必须告诉它是只是做某件事还是做某事,然后返回结果 The way to tell a function is the return statement. 告诉函数的方法是return语句。 In your functions, you have just told to do something. 在您的职能中,您刚刚被告知要做某事。 And that is print "......" so does the functions. 那就是print "......" ,功能也一样。 You call the with () at end and the does their work, they prints it. 您最后用()调用with,然后做他们的工作,他们打印出来。 But as I said if you don't tell it to return a result, it won't. 但是正如我说的,如果您不告诉它返回结果,它将不会。 And because it is not returning any result, nothing will be assigned with the variable (don't confuse him with None ). 而且由于它没有返回任何结果,因此不会为该变量分配任何内容(不要将其与None混淆)。 When you wrote those lines (if in interpreter) or run the script, you will see those lines printed but your zap and thing has no values. 当你写的那些线(如果解释器)或运行脚本,你会看到这些行打印,但您的zapthing有没有价值。

So how to fix it? 那么如何解决呢? Tell them to return the lines to the variables. 告诉他们将行返回到变量。 To tell the functions do that, replace the print statements with return statements. 为了告诉函数这样做,请用return语句替换print语句。 And never mind to experiment what you know, to know about what you know about your knowledge is true :-) 而且不要介意试验您所知道的,知道您对知识的了解是真的:-)

Hope it helps :-) 希望能帮助到你 :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM