Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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

Saturday = cookies()

but just thinking "hey, Saturday is cookie day" is not the same as actually baking cookies... so why does just saying

Saturday = cookies()

actually bake the cookies, rather than just setting up Saturday with the variable "cookies()" for some later use?

like image 605
JeanSibelius Avatar asked Mar 11 '12 14:03

JeanSibelius


3 Answers

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()
like image 64
El Barto Avatar answered Nov 08 '22 13:11

El Barto


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. The function foo could be executed by f().

f = foo()

This calls the function foo and binds the return value to 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.

like image 24
David Heffernan Avatar answered Nov 08 '22 13:11

David Heffernan


Although it may seem like your functions don't return anything, they do in fact. Quoting the Python.org documentation:

The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns 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 (i.e. the value of pants()), and to thing whatever shorts returns. In your case, both are None, but of course the functions must be run in order to figure this out(*). Afterall, it could be that pants returns 42 during leap years, and that shorts returns 'Foobar' whenever some random number generator "rolls" a 6.


(*) 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. But a function that prints something (or inspects whether the current year is a leap year, or rolls a die) won't be pure.

like image 21
gspr Avatar answered Nov 08 '22 14:11

gspr