2

I'm new to python and was playing with worked examples textbook from http://do1.dr-chuck.com/pythonlearn/EN_us/pythonlearn.pdf section.4.9 user defined functions. I got confused along the way.

(I was pointed to post Short description of the scoping rules? but all its answers but found it too advanced for my beginner-level question )

when code round0 was:

bruce=input("please enter what to be printed 2x")
def printTwice(bruce):
    print(bruce)
    print(bruce)
printTwice("alpha") 

regardless of what input i gave, it came out as "alpha". OK , i get it, "alpha" is set as value for "bruce" here.

round1:

bruce=input("please enter what to be printed 2x") #to input "hello"
not1=123
def printTwice(not1): #set parameter to not1 , not1 is set as 123 , but output is what was given in input 
    print(bruce)
    print(bruce)
printTwice("a") 

output turns out to be whatever is inputted for bruce. e.g. "hello"

Q: Why does it ignore arguments "a" and "not1" and take input "hello" for bruce ?

Round 2: #Since i saw python wasn't paying attention to what i ask it to do, i removed quotes for "a" , to be a

bruce=input("please enter what to be printed 2x")
not1=123
def printTwice(not1): #set parameter to not1 , not1 is set as 123 , but output is what was given in input 
    print(bruce)
    print(bruce)
printTwice(a)  # argument doesn't have " " now

outcome : NameError: name 'a' is not defined. Q: why does it now bother what i placed into the parenthesis this time but not round 0 nor round 1?

I understand my question is beginner or maybe duplicated somewhere, if so, please point me to the right post. Thank you!

x t
  • 23
  • 4
  • 1
    I think you have some... fundamental misunderstanding...? Anyway I recommend reading the official Python tutorial [The Python Tutorial — Python 3.10.0 documentation](https://docs.python.org/3/tutorial/) , if you're not. – user202729 Dec 06 '21 at 06:54

1 Answers1

3

There are some facts here:

  1. When you define a parameter for your function, it becomes a "local variable" to that function.
  2. Local variables always shadow the global variables the variables defined in the module. (let's skip the global keyword for now).
  3. There is a LEGB rule, which Python cares when trying to find names(variables). They stands for Local-Enclosing-Global-Builtin. It searches the names in that order exactly.

In round0 you defined bruce as a parameter, so it will shadow the global variable bruce. That's why the bruce inside the function is exactly the parameter which is local variable. You can think of creating a variable bruce = 'alpha' inside the function. It shadow the variable bruce in the global namespace which has the result of input()

In round1 you defined not1 as a parameter but you never used that variable. Instead you used the variable bruce which is not a local variable because it is not defined inside the function, or as a parameter. Now Python goes forward too see if it can find it in global namespace...

round2 is a different story... Don't confuse the names you put as parameters, and the names you put as arguments. If you put a name like bruce to the parameter (as I mentioned above) you are creating a local variable. just like you say bruce = 10 inside the function. But here when you pass a to a function while you are calling it, you are actually pass an object to that function. a must be exist before. You did not get error in previous cases because you pass an object (string object 'a' and 'alpha' to the function. You also wouldn't get error if you have something like a = 10 before calling the function with printTwice(a), Because now a points to the object 10.

If you put names as parameters, Python creates a local variable for you, If you pass something to the arguments, Python evaluates it first(that's why you have to have them before) and send the actual (reference to that) object to the function's parameter.

S.B
  • 13,077
  • 10
  • 22
  • 49