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?
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. 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With