2

Why does print(squared) return 0 instead of 100?

I thought that after being returned from the function - the value of the variable squared would be assigned to the the global variable with the same name?

squared = 0
def square(n):
    """Returns the square of a number."""
    squared = n**2
    print "%d squared is %d." % (n, squared)
    return squared


square(10)
print(squared)

returns:

enter image description here

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
ruben_KAI
  • 325
  • 6
  • 18

4 Answers4

5

Assign the result of the function to the variable:

squared = square(10)

This is the whole point of using return squared in the function, isn't it?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Yes absolutely, thank you! Just a disclaimer for newcomers: If you're somewhat of a beginner, and you're using IDE - something like... `def simple() print 5 return 10` ... will 'print' both 5 and 10 - this can be intuitive misleading. Here is a good video that gave me a better intuition behind print and return: https://www.youtube.com/watch?v=2CythYpk7c0 – ruben_KAI Sep 02 '15 at 23:13
  • 1
    @Ruben, You'll only see the 10 (the returned value) if you execute this function from the interpreter prompt. In a regular script, returned values that are not assigned to a variable simply disappear. Focus your thoughts on that, and not on accidents of the interpreter. – alexis Sep 03 '15 at 13:10
3

The function square never changes the variable squared that is found in the global scope. Inside the function you declare a local variable with the same name as the global variable, this however will change the local variable and not the global variable. Then when you print(squared) you are printing that unchanged global variable which is still 0 as you initially set it. As a matter of code cleanliness you really should try to avoid having local variables and global variables sharing the same name as it causes confusion (as we have seen in this question) and makes the code much harder to read.

To change the global variable from within a function you must tell Python to do so by using the global keyword to make the name refer to the global variable. You might want to look at this question: Use of "global" keyword in Python

The easier and better option of course is just to use the return value of the function. Minimizing the use of global mutable state is a good goal.

Community
  • 1
  • 1
shuttle87
  • 15,466
  • 11
  • 77
  • 106
1

Essentially what is happening here is you are creating a local variable in the square function. To change squared, simply type:

squared =square(10)
print squared
John
  • 2,410
  • 1
  • 19
  • 33
-1

Sort of. Your very close. You need to change the following:

def square(n):
    """Returns the square of a number."""
    squared = n**2

To:

def square(n):
    """Returns the square of a number."""
    global squared

    squared = n**2

Hope this helps!

Vale Tolpegin
  • 77
  • 1
  • 9
  • 2
    No, you do not need to change it to that! **There is absolutely no reason for this variable to be global.** The OP _expects_ it to be global, but the OP has already demonstrated a lack of understanding of normal scoping rules, and possibly the concept of scoping. Teaching them to abuse global scope instead of understanding the real problem is just really bad advice. – Two-Bit Alchemist Sep 02 '15 at 22:47
  • "the value of the variable squared would be assigned to the the global variable with the same name?"... The variable needs to be globally declared before that will be true. – Vale Tolpegin Sep 02 '15 at 22:48
  • I understand that this is not the right way of programming in Python - but this answered explained the question I had about how Python handles scope and how variables are returned. I'm going to accept this answer with a disclaimer. *** THIS IS NOT GOOD PRACTICE *** But it answers me original question - and might server to give someone with the same question that I had a better intuition. – ruben_KAI Sep 02 '15 at 22:50
  • @RubenBaden Then I hope you also understand that this is just advice gleaned from years of people doing things that caused them headaches. It's not about "the right way of programming in Python", because there is no such thing in a multi-paradigm language. Rather, it's about a way of programming that causes the least amount of debugging stress -- mucking around with things in the global scope just makes it unnecessarily hard to reason about state at any given point of execution within your program. – Two-Bit Alchemist Sep 02 '15 at 22:51
  • @Two-BitAlchemist - You made your point very clear; and I appreciate it. I know how much of a headache global variables can be. There are some languages, however, that would have returned the value globally - right? I will make sure to avoid this - and I probably won't forget the tip; given your emotional testimonial. Thank you. – ruben_KAI Sep 02 '15 at 22:56
  • 1
    @RubenBaden Might be a good question on Programmers.SE, as I'm not an expert on a huge number of languages. As far as I know, most imperative languages in the extended C family, if you will, behave just as Python does here: a local scope is introduced in the function and global things are not modified unless explicitly requested (e.g., `global squared` in your example). To me, function scope is almost the most basic type, and I suspect languages that don't have it are languages where the concept of scope is very weak or not present at all. – Two-Bit Alchemist Sep 02 '15 at 23:04
  • 1
    @Two-BitAlchemist That wouldn't be a good Programmers question since it's essentially asking for a list of languages. But I agree that the vast majority of popular, mainstream languages follow the rule that variables "re-declared" in a narrower scope will "hide" the preexisting ones rather than reference them. – Ixrec Sep 02 '15 at 23:11
  • @lxrec Hmm, even if you asked something like, "Is there function scope in every language?" (which is falsifiable with a single counter-example) I agree anything soliciting a list of even families of languages is just bait for closing as "too broad". – Two-Bit Alchemist Sep 02 '15 at 23:13
  • "There are some languages, however, that would have returned the value globally - right?" **Wrong!** No language could work this way, because this statement confuses values with variables. A returned **value** is neither global nor local, there is nothing to discuss or compare in other languages. – alexis Sep 03 '15 at 14:54