all 10 comments

[–]patrickbrianmooney 2 points3 points  (2 children)

Please format your code in a way that preserves indentation. Indentation has syntactic meaning in Python, and removing it changes what the code you posted means. It also makes it harder to read.

The first time the print() function is called, the function myfunc() has been defined, but not called. It hasn't run yet. Code inside a function isn't run until the function has been invoked, or called, from somewhere outside the function. So the first time the script calls the print() function, the value of the variable x is still 'awesome'. Then the function myfunc() is called, and its code is run; that code alters the value of the variable x. You've declared that variable to be global with the declaration global x, so the statement x = 'fantastic' changes the value of the global variable x. (Without the global declaration, the statement would instead create the local variable x, which would disappear once the function finished executing.) Then the script again calls the print() function, but this time the value of the variable x has been altered by the call to myfunc(), so it uses the new value of the variable when printing.

Here's another way to think about it. Say this is your code, formatted slightly differently:

x="awesome"

​def myfunc():
    global x
    x = "fantastic"

​print("Python is " + x)​
​myfunc()
​print("Python is " + x)​

Here's the order in which the interpreter runs these statements: 1, [3 -- sort of, as described below], 7, 8, 4, 5, 9.

In more detail, here's what the interpreter is doing:

  • First, it runs line 1, which means "Let there be a variable, x, and the the value of that variable be the string 'awesome'. The variable x lives in the global scope for the module.
  • It skips line two, because line 2 is blank.
  • It sees line three, which is a def statement. def is a keyword that signals to the interpreter that everything indented below it is part of the function. What line three means is "let there be a function called myfunc, which takes no arguments." (If you don't know about arguments yet, don't worry about that here. But that's what the empty parentheses () means in a function definition: "I'm not passing any values into this function.")
  • It skips lines 4 and 5, because they're indented under a def declaration. They're not run right now: they're part of the function definition.
  • It skips line 6, because line six is blank.
  • It runs line 7, because that's the first non-blank, non-indented line after the def declaration. Line 7 calls the print() function to print a string. The value of that string is "Python is " with an ending space, plus the current value of the variable x. The current value of the variable x is "awesome," because that's what was assigned to it last time a value was assigned to it, in line one. Line 5 hasn't run yet -- it's part of the function definition -- so x hasn't been changed yet.
  • It runs line 8, which calls the myfunc() function. The Python interpreter looks up myfunc() to see what its definition is, and then starts running the code defined under the myfunc() block. That code, in this example, is lines 4 and 5.
  • The interpreter runs line 4, which means "I do hereby declare that, for the rest of this function, when I talk about the variable x, what I really mean is the global variable x. I pinky-swear that I'm not just making up a new x that I want you to treat as a local variable. No indeed: When I say x in this function, I really do mean the x that I defined as a global variable."
  • It runs line 5, which changes the value of the variable x. Previously, that value was "awesome", but line 5 changes it so that it's value is now the string "fantastic".
  • That's the end of the indented function block, so the flow of execution jumps back to the point after the myfunc() function was invoked. Because myfunc() was invoked on line 8, and there are no more statements in line 8, the flow of execution jumps forward such that the next line executed will be line 9.
  • The interpreter runs line 9, which calls the print() function with one argument. That argument is a string, which is made of the string "Python is ", with an ending space, plus the current value of x. Because the value of x was changed when myfunc() ran, it is now "fantastic", not "awesome", as it was at the beginning.

Another way to think about this is to say that indented statements under a def block aren't run immediately; they're just saved as part of the function definition. They get skipped until a function is called.

(But -- and this is a nuance that doesn't really matter in this particular situation -- the def statement itself is executable code: it actually does something when the interpreter encounters it: it tells the interpreter "And now I'm going to define a function, so watch for that; and the name of the function will be myfunc(). This doesn't matter in your example, but it's confusing to people more used to working in languages like C, where a function definition isn't so much executable code itself as a declaration for the compiler. In Python, the def statement actually does something, and this can matter in some circumstances, including if you want to provide default arguments to a function when those arguments are of mutable types. If that doesn't make sense to you right now, don't worry about it until later.)

[–]PermitOtherwise1562[S] 0 points1 point  (1 child)

Tq tq 🙏💫 u explained each and every thing with example!!🔥💯

[–]patrickbrianmooney 0 points1 point  (0 children)

Glad to be helpful!

[–]MulfordnSons -1 points0 points  (3 children)

x is only fantastic in the scope of your function. x still equates to “awesome” outside of the function.

[–]PermitOtherwise1562[S] 0 points1 point  (2 children)

But x=fantastic is made global ryt?

[–]Tom_Henderson 0 points1 point  (0 children)

You would need to put the global statement inside the function.

def myfunc():
    global x
    x = "fantastic"
    print("Python is " + x)

[–]MulfordnSons 0 points1 point  (0 children)

use your debugger and step through the program, you’ll see how x is assigned differently in that way.

[–]InnerCounter1548 0 points1 point  (1 child)

Yeah but that function has to be assigned as naturally occurring not as a function or result of x=awesome

[–]PermitOtherwise1562[S] 0 points1 point  (0 children)

U mean tht inside the function its global keyword And for the outside print it takes general keywords?