Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am reading the book Python Programming for the Absolute Beginner by Mike Dawson and I was struck by a question that I had regarding functions.
Observing the code below
def func_1():
name = input('What is your name?')
def func_2():
print(name)
func_2()
I know that I cannot call the variable name in function 2 as it is local to function 1.
However, why can I call a function inside another function and then find the value of the user's input as such below?
def func_1():
name = input('What is your name?')
return name
def func_2():
user_input = func_1()
print(user_input)
func_2()
The important thing to consider here is the scope of the variable and/or function names you're using. Global scope means everything can see it, whether it's at the top level, inside a function, or even inside a method, which is inside a class.
Local scope means it's locked within the context of that block, and nothing outside of the block can see it. In your case, that block is a function.
(Note that this is a mild simplification and more complex rules exist around modules and includes, but this is a reasonable starter for 10...).
In your example above, the function has been defined at the global level, so its name, func_1 has global scope (you might also say that it is in the "global namespace". That means that anything can see it, including code inside other functions.
Conversely, the variable name has local scope, inside func_1, which means it is only visible inside func_1, and nowhere else.
When you return name, you're passing the value of name back to whatever called that function. That means that the user_input = func_1() receives the value that was returned and stores it in a new variable, called user_input.
The actual variable name is still only visible to func_1, but that value has been exposed to outside functions by returning it.
Edit: As requested by #Chris_Rands:
There is a function in Python that will give you a dictionary containing of all the global variables currently available in the program.
This is the globals() function. You can check something is at global scope by seeing if it is in this dictionary:
def func_1():
name = input('What is your name?')
def func_2():
print(name)
func_1_is_global = 'func_1' in globals() # value is 'True'
name_is_global = 'name' in globals() # value is 'False'
One additional edit for completeness: I state above that you're passing the value of name back. This is not strictly true as Python is pass-by-reference, but the waters get murky here and I didn't want to confuse the issue. More details here for the interested observer: How do I pass a variable by reference?
func_2 calls func1, which returns a value which you can print inside func_2. In your first example func_2 cannot see a local variable of function_1.
Related
I had a math test today and one of the extra credit questions on the test was
product = 1
for i in range(1,7,2):
print i
product = product * i
print i
print product
We were supposed to list out the steps of the loop which was easy; but it got me thinking, why does this program run? the second print i seems out of place to me. I would think that the i only exists for the for loop and then get's destroyed so when you call the second print i there is no variable i and you get an error.
Why does i remain a global variable?
The Devil is in the Details
Naming and binding
A block is a piece of Python program text that is executed as a unit.
The following are blocks: a module, a function body, and a class
definition.
Or in simple words, a for loop is not a block
A scope defines the visibility of a name within a block. If a local
variable is defined in a block, its scope includes that block. If the
definition occurs in a function block, the scope extends to any blocks
contained within the defining one, unless a contained block introduces
a different binding for the name.
So any variable defined is visible from the point of definition to the end of scope of the block, function, module or class definition.
Why does i remain a global variable?
From the nomenclature parlance, I will call i a global variable, if your highlighted code is part of the module rather than a defined function.
Python does not have block scope. Any variables defined in a function are visible from that point only, until the end of the function.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to understand function environments (global, local). Specifically, I get very confused when there is a nested function that has already been defined globally, for example:
def g(x):
print(x)
def f(f):
f(1)
f(g)
Can someone please help me with this concept? I would greatly appreciate it.
Thanks.
Python uses dictionaries to keep local and global variables in. When looking up a variable reference, it will look into the local dict first. If you want to reference a variable in the global dictionary, put the global keyword in front of it.
Also see answers to this question for more elaborate info.
I agree with user18044, however, is your confusion about the ’f(f)’? I agree that can be really confusing, especially in a non typed language. The argument to ’f’ is a function handle that has a local type scope with name ’f’. The way python decides which ’f’ gets used is explained by 18044. Python looks at the name ’f’ on the function definition and the local parameter ’f’ takes precidence over the global name ’f’ just like would be done if we had a global variable ’dude’ and a local variable ’dude’ in a function. The local overrides the global. Hopes this helps, and makes sense. :-)
The locals for a function consist of everything that was passed in, and every variable that is assigned to and not explicitly tagged as global (or nonlocal in 3.x).
The globals consist of everything that can be seen at global scope, including the function itself.
When a name is referenced, it is looked up in the locals first, and then in the globals if not found in the locals.
When the statement f(g) is run, the statement itself is at global scope, so there are no locals. f and g are both found in the globals: they are both functions. The function defined by def f... is called, with the function defined by def g... being passed as an argument.
When f(f) runs, f is in the locals for the function. It is bound to the passed-in value, which is the function defined by def g.... The body of the function has the statement f(1). 1 is a constant and no lookup is required. f is looked up in the locals, and the passed-in function is found. It - being the function known at global scope as g - is called.
Thus g is, likewise, run with the value 1 bound to the local variable x. That is forwarded to the function print (in 3.x; in 2.x, print is a keyword, so print x is a statement), which prints the value 1.
This question already has answers here:
What's the scope of a variable initialized in an if statement?
(7 answers)
Closed 3 years ago.
In Python, are variable scopes inside if-statements visible outside of the if-statement? (coming from a Java background, so find this a bit odd)
In the following case, name is first defined inside the if-block but the variable is visible outside of the if-block as well. I was expecting an error to occur but 'joe' gets printed.
if 1==1:
name = 'joe'
print(name)
if statements don't define a scope in Python.
Neither do loops, with statements, try / except, etc.
Only modules, functions and classes define scopes.
See Python Scopes and Namespaces in the Python Tutorial.
Yes, in Python, variable scopes inside if-statements are visible outside of the if-statement.
Two related questions gave an interestion discussion:
Short Description of the Scoping Rules?
and
Python variable scope error
All python variables used in a function live in the function level scope. (ignoring global and closure variables)
It is useful in case like this:
if foo.contains('bar'):
value = 2 + foo.count('b')
else:
value = 0
That way I don't have to declare the variable before the if statement.
I'm currently developing some things in Python and I have a question about variables scope.
This is the code:
a = None
anything = False
if anything:
a = 1
else:
a = 2
print a # prints 2
If I remove the first line (a = None) the code still works as before. However in this case I'd be declaring the variable inside an "if" block, and regarding other languages like Java, that variable would only be visible inside the "if".
How exactly variable scoping works in Python and what's the good way to program in cases like this?
Thanks!
As a rule of thumb, scopes are created in three places:
File-scope - otherwise known as module scope
Class-scope - created inside class blocks
Function-scope - created inside def blocks
(There are a few exceptions to these.)
Assigning to a name reserves it in the scope namespace, marked as unbound until reaching the first assignment. So for a mental model, you are assigning values to names in a scope.
I believe that Python uses function scope for local variables. That is, in any given function, if you assign a value to a local variable, it will be available from that moment onwards within that function until it returns. Therefore, since both branches of your code are guaranteed to assign to a, there is no need to assign None to a initially.
Note that when you can also access variables declared in outer functions -- in other words, Python has closures.
def adder(first):
def add(second):
return first + second
return add
This defines a function called adder. When called with an argument first, it will return a function that adds whatever argument it receives to first and return that value. For instance:
add_two = adder(2)
add_three = adder(3)
add_two(4) # = 6
add_three(4) # = 7
However, although you can read the value from the outer function, you can't change it (unlike in many other languages). For instance, imagine trying to implement an accumulator. You might write code like so:
def accumulator():
total = 0
def add(number):
total += number
return total
return add
Unfortunately, trying to use this code results in an error message:
UnboundLocalError: local variable 'total' referenced before assignment
This is because the line total += number tries to change the value of total, which cannot be done in this way in Python.
There is no problem assigning the variable in the if block.
In this case it is being assigned on both branches, so you can see it will definitely be defined when you come to print it.
If one of the branches did not assign to a then a NameError exception would be raise when you try to print it after that branch
Python doesn't need variables to be declared initially, so you can declare and define at arbitrary points. And yes, the scope is function scope, so it will be visible outside the if.
i'm quite a beginner programmer, but for what i know, in python private variables don't exist. see private variables in the python documentation for a detailed discussion.
useful informations can also be found in the section "scopes and namespaces" on the same page.
personally, i write code like the one you posted pretty much every day, especially when the condition relies in getting input from the user, for example
if len(sys.argv)==2:
f = open(sys.argv[1], 'r')
else:
print ('provide input file')
i do declare variables before using them for structured types, for example i declare an empty list before appending its items within a loop.
hope it helps.
I am a beginner of python and have a question, very confusing for me.
If I define a function first but within the function I have to use a variable which is defined in another function below, can I do it like this? Or how can I import the return things of another function into a function?
for example:
def hello(x,y):
good=hi(iy,ix)
"then do somethings,and use the parameter'good'."
return something
def hi(iy,ix):
"code"
return good
The scope of functions hello and hi are entirely different. They do not have any variables in common.
Note that the result of calling hi(x,y) is some object. You save that object with the name good in the function hello.
The variable named good in hello is a different variable, unrelated to the variable named good in the function hi.
They're spelled the same, but the exist in different namespaces. To prove this, change the spelling the good variable in one of the two functions, you'll see that things still work.
Edit. Follow-up: "so what should i do if i want use the result of hi function in hello function?"
Nothing unusual. Look at hello closely.
def hello(x,y):
fordf150 = hi(y,x)
"then do somethings,and use the variable 'fordf150'."
return something
def hi( ix, iy ):
"compute some value, good."
return good
Some script evaluates hello( 2, 3).
Python creates a new namespace for the evaluation of hello.
In hello, x is bound to the object 2. Binding is done position order.
In hello, y is bound to the object 3.
In hello, Python evaluates the first statement, fordf150 = hi( y, x ), y is 3, x is 2.
a. Python creates a new namespace for the evaluation of hi.
b. In hi, ix is bound to the object 3. Binding is done position order.
c. In hi, iy is bound to the object 2.
d. In hi, something happens and good is bound to some object, say 3.1415926.
e. In hi, a return is executed; identifying an object as the value for hi. In this case, the object is named by good and is the object 3.1415926.
f. The hi namespace is discarded. good, ix and iy vanish. The object (3.1415926), however, remains as the value of evaluating hi.
In hello, Python finishes the first statement, fordf150 = hi( y, x ), y is 3, x is 2. The value of hi is 3.1415926.
a. fordf150 is bound to the object created by evaluating hi, 3.1415926.
In hello, Python moves on to other statements.
At some point something is bound to an object, say, 2.718281828459045.
In hello, a return is executed; identifying an object as the value for hello. In this case, the object is named by something and is the object 2.718281828459045.
The namespace is discarded. fordf150 and something vanish, as do x and y. The object (2.718281828459045), however, remains as the value of evaluating hello.
Whatever program or script called hello gets the answer.
If you want to define a variable to the global namespace from inside a function, and thereby make it accessible by other functions in this space, you can use the global keyword. Here's some examples
varA = 5 #A normal declaration of an integer in the main "global" namespace
def funcA():
print varA #This works, because the variable was defined in the global namespace
#and functions have read access to this.
def changeA():
varA = 2 #This however, defines a variable in the function's own namespace
#Because of this, it's not accessible by other functions.
#It has also replaced the global variable, though only inside this function
def newVar():
global varB #By using the global keyword, you assign this variable to the global namespace
varB = 5
def funcB():
print varB #Making it accessible to other functions
Conclusion: variables defined in a function stays in the function's namespace. It still has access to the global namespace for reading only, unless the variable has been called with the global keyword.
The term global isn't entirely global as it may seem at first. It's practically only a link to the lowest namespace in the file you're working in. Global keywords cannot be accessed in another module.
As a mild warning, this may be considered to be less "good practice" by some.
your example program works, because the two instances of 'good' are different variables (you just happen to have both variables with the same name). The following code is exactly the same:
def hello(x,y):
good=hi(iy,ix)
"then do somethings,and use the parameter'good'."
return something
def hi(iy,ix):
"code"
return great
More details on the python scoping rules are here :
Short Description of Python Scoping Rules
The "hello" function doesn't mind you calling the "hi" function which is hasn't been defined yet, provided you don't try to actually use the "hello" function until after the both functions have been defined.