I'm debugging a program. In the debug console, I decided to write the following function:
def func():
global a
a=5
func()
a
a is undefined!
Why does this happens in the debug console?
If you want to use a outside function, you should declare it first.
a = 0
def func():
global a
a=5
func()
print(a)
In this case will be 6 and 3
test=6
def func():
global test
print(test)
test=3
f()
print(test)
FYI: What are the rules for local and global variables in Python?
In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.
Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.
Related
I have a code in which I declare a variable globally. Then inside a function, when I try to use it, it gives an error Unbound variable is not declared
My code:
count_url =1
def foo():
...
ttk.Label(canvas1, text=f'{varSongTitle}...Done! {count_url}/{str(var_len)}').pack(padx=3,pady=3)
root.update()
count_url = count_url + 1
When I read from here that for bypassing this issue: The issue as I guess was that inside function my globally declared variable was becoming local, I guess because after printing it out I was assigning it to count_url =+ That's why I needed to also decalre it globally inside function as below:
count_url =1
def foo():
global count_url
...
ttk.Label(canvas1, text=f'{varSongTitle}...Done! {count_url}/{str(var_len)}').pack(padx=3,pady=3)
root.update()
count_url = count_url + 1
Now code works perfectly! But I have pair of questions How? Why?. Why it does not behave similarly if I assign global in global scope like
global count_url
count_url=1
def foo():
...
And also How can this be possible, that due to assigning inside the function a value to my global variable, why it becomes local?
ANSWER: https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.
The default behavior of Python is to create a new variable in the function scope without checking the global scope for a similarly named variable.
The global declaration inside the function tells Python that you want to use the variable declared in the outer scope instead of creating a new one.
Adding a reference to the official Python documentation, from a comment: https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
I'm relatively new to Python, so please forgive my ignorance.
I have two functions acting on a single variable var:
var = 8
def func1():
print(var)
def func2():
var += 1
print(var)
func2 will not function unless I define var as a global variable:
def func2():
global var
var += 1
print(var)
What is the functionality that allows me to call global variables (as in func1) but does not allow me to redefine global variables without explicitly calling them first (as in func2)?
The Programming FAQ explains the reasoning:
In Python, variables that are only referenced inside a function are
implicitly global. If a variable is assigned a value anywhere within
the function’s body, it’s assumed to be a local unless explicitly
declared as global.
Though a bit surprising at first, a moment’s consideration explains
this. On one hand, requiring global for assigned variables provides a
bar against unintended side-effects. On the other hand, if global was
required for all global references, you’d be using global all the
time. You’d have to declare as global every reference to a built-in
function or to a component of an imported module. This clutter would
defeat the usefulness of the global declaration for identifying
side-effects.
From my understanding, Python has a separate namespace for functions, so if I want to use a global variable in a function, I should probably use global.
However, I was able to access a global variable even without global:
>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
... return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'
Why does this work?
See also UnboundLocalError on local variable when reassigned after first use for the error that occurs when attempting to assign to the global variable without global. See Using global variables in a function for the general question of how to use globals.
The keyword global is only useful to change or create global variables in a local context, although creating global variables is seldom considered a good solution.
def bob():
me = "locally defined" # Defined only in local context
print(me)
bob()
print(me) # Asking for a global variable
The above will give you:
locally defined
Traceback (most recent call last):
File "file.py", line 9, in <module>
print(me)
NameError: name 'me' is not defined
While if you use the global statement, the variable will become available "outside" the scope of the function, effectively becoming a global variable.
def bob():
global me
me = "locally defined" # Defined locally but declared as global
print(me)
bob()
print(me) # Asking for a global variable
So the above code will give you:
locally defined
locally defined
In addition, due to the nature of python, you could also use global to declare functions, classes or other objects in a local context. Although I would advise against it since it causes nightmares if something goes wrong or needs debugging.
While you can access global variables without the global keyword, if you want to modify them you have to use the global keyword. For example:
foo = 1
def test():
foo = 2 # new local foo
def blub():
global foo
foo = 3 # changes the value of the global foo
In your case, you're just accessing the list sub.
This is the difference between accessing the name and binding it within a scope.
If you're just looking up a variable to read its value, you've got access to global as well as local scope.
However if you assign to a variable who's name isn't in local scope, you are binding that name into this scope (and if that name also exists as a global, you'll hide that).
If you want to be able to assign to the global name, you need to tell the parser to use the global name rather than bind a new local name - which is what the 'global' keyword does.
Binding anywhere within a block causes the name everywhere in that block to become bound, which can cause some rather odd looking consequences (e.g. UnboundLocalError suddenly appearing in previously working code).
>>> a = 1
>>> def p():
print(a) # accessing global scope, no binding going on
>>> def q():
a = 3 # binding a name in local scope - hiding global
print(a)
>>> def r():
print(a) # fail - a is bound to local scope, but not assigned yet
a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
r()
File "<pyshell#32>", line 2, in r
print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>>
The other answers answer your question. Another important thing to know about names in Python is that they are either local or global on a per-scope basis.
Consider this, for example:
value = 42
def doit():
print value
value = 0
doit()
print value
You can probably guess that the value = 0 statement will be assigning to a local variable and not affect the value of the same variable declared outside the doit() function. You may be more surprised to discover that the code above won't run. The statement print value inside the function produces an UnboundLocalError.
The reason is that Python has noticed that, elsewhere in the function, you assign the name value, and also value is nowhere declared global. That makes it a local variable. But when you try to print it, the local name hasn't been defined yet. Python in this case does not fall back to looking for the name as a global variable, as some other languages do. Essentially, you cannot access a global variable if you have defined a local variable of the same name anywhere in the function.
Accessing a name and assigning a name are different. In your case, you are just accessing a name.
If you assign to a variable within a function, that variable is assumed to be local unless you declare it global. In the absence of that, it is assumed to be global.
>>> x = 1 # global
>>> def foo():
print x # accessing it, it is global
>>> foo()
1
>>> def foo():
x = 2 # local x
print x
>>> x # global x
1
>>> foo() # prints local x
2
You can access global keywords without keyword global
To be able to modify them you need to explicitly state that the keyword is global. Otherwise, the keyword will be declared in local scope.
Example:
words = [...]
def contains (word):
global words # <- not really needed
return (word in words)
def add (word):
global words # must specify that we're working with a global keyword
if word not in words:
words += [word]
This is explained well in the Python FAQ
What are the rules for local and global variables in Python?
In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.
Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.
https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python
Any variable declared outside of a function is assumed to be global, it's only when declaring them from inside of functions (except constructors) that you must specify that the variable be global.
global makes the variable visible to everything in the module, the modular scope, just as if you had defined it at top-level in the module itself. It's not visible outside the module, and it cannot be imported from the module until after it has been set, so don't bother, that's not what it is for.
When does global solve real problems? (Note: Checked only on Python 3.)
# Attempt #1, will fail
# We cannot import ``catbus`` here
# as that would lead to an import loop somewhere else,
# or importing ``catbus`` is so expensive that you don't want to
# do it automatically when importing this module
top_level_something_or_other = None
def foo1():
import catbus
# Now ``catbus`` is visible for anything else defined inside ``foo()``
# at *compile time*
bar() # But ``bar()`` is a call, not a definition. ``catbus``
# is invisible to it.
def bar():
# `bar()` sees what is defined in the module
# This works:
print(top_level_something_or_other)
# This doesn't work, we get an exception: NameError: name 'catbus' is not defined
catbus.run()
This can be fixed with global:
# Attempt #2, will work
# We still cannot import ``catbus`` here
# as that would lead to an import loop somewhere else,
# or importing ``catbus`` is so expensive that you don't want to
# do it automatically when importing this module
top_level_something_or_other = None
def foo2():
import catbus
global catbus # Now catbus is also visible to anything defined
# in the top-level module *at runtime*
bar()
def bar():
# `bar` sees what is defined in the module and when run what is available at run time
# This still works:
print(top_level_something_or_other)
# This also works now:
catbus.run()
This wouldn't be necessary if bar() was defined inside foo like so:
# Attempt 3, will work
# We cannot import ``catbus`` here
# as that would lead to an import loop somewhere else,
# or importing ``catbus`` is so expensive that you don't want to
# do it automatically when importing this module
top_level_something_or_other = None
def foo3():
def bar():
# ``bar()`` sees what is defined in the module *and* what is defined in ``foo()``
print(top_level_something_or_other)
catbus.run()
import catbus
# Now catbus is visible for anything else defined inside foo() at *compile time*
bar() # Which now includes bar(), so this works
By defining bar() outside of foo(), bar() can be imported into something that can import catbus directly, or mock it, like in a unit test.
global is a code smell, but sometimes what you need is exactly a dirty hack like global. Anyway, "global" is a bad name for it as there is no such thing as global scope in python, it's modules all the way down.
It means that you should not do the following:
x = 1
def myfunc():
global x
# formal parameter
def localfunction(x):
return x+1
# import statement
import os.path as x
# for loop control target
for x in range(10):
print x
# class definition
class x(object):
def __init__(self):
pass
#function definition
def x():
print "I'm bad"
Global makes the variable "Global"
def out():
global x
x = 1
print(x)
return
out()
print (x)
This makes 'x' act like a normal variable outside the function. If you took the global out then it would give an error since it cannot print a variable inside a function.
def out():
# Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
x = 1
print(x)
return
out()
print (x)
In Python 3.3.1, this works:
i = 76
def A():
global i
i += 10
print(i) # 76
A()
print(i) # 86
This also works:
def enclosing_function():
i = 76
def A():
nonlocal i
i += 10
print(i) # 76
A()
print(i) # 86
enclosing_function()
But this doesn't work:
i = 76
def A():
nonlocal i # "SyntaxError: no binding for nonlocal 'i' found"
i += 10
print(i)
A()
print(i)
The documentation for the nonlocal keyword states (emphasis added):
The nonlocal statement causes the listed identifiers to refer to
previously bound variables in the nearest enclosing scope.
In the third example, the "nearest enclosing scope" just happens to be the global scope. So why doesn't it work?
PLEASE READ THIS BIT
I do notice that the documentation goes on to state (emphasis added):
The [nonlocal] statement allows encapsulated code to
rebind variables outside of the local scope besides the global
(module) scope.
but, strictly speaking, this doesn't mean that what I'm doing in the third example shouldn't work.
The search order for names is LEGB, i.e Local, Enclosing, Global, Builtin. So the global scope is not an enclosing scope.
EDIT
From the docs:
The nonlocal statement causes the listed identifiers to refer to
previously bound variables in the nearest enclosing scope. This is
important because the default behavior for binding is to search the
local namespace first. The statement allows encapsulated code to
rebind variables outside of the local scope besides the global
(module) scope.
why is a module's scope considered global and not an enclosing one? It's still not global to other modules (well, unless you do from module import *), is it?
If you put some name into module's namespace; it is visible in any module that uses module i.e., it is global for the whole Python process.
In general, your application should use as few mutable globals as possible. See Why globals are bad?:
Non-locality
No Access Control or Constraint Checking
Implicit coupling
Concurrency issues
Namespace pollution
Testing and Confinement
Therefore It would be bad if nonlocal allowed to create globals by accident. If you want to modify a global variable; you could use global keyword directly.
global is the most destructive: may affect all uses of the module anywhere in the program
nonlocal is less destructive: limited by the outer() function scope (the binding is checked at compile time)
no declaration (local variable) is the least destructive option: limited by inner() function scope
You can read about history and motivation behind nonlocal in PEP: 3104
Access to Names in Outer Scopes.
It depends upon the Boundary cases:
nonlocals come with some senstivity areas which we need to be aware of. First, unlike the global statement, nonlocal names really must have previous been assigned in an enclosing def's scope when a nonlocal is evaluated or else you'll get an error-you cannot create them dynamically by assigning them anew in the enclosing scope. In fact, they are checked at function definition time before either or nested function is called
>>>def tester(start):
def nested(label):
nonlocal state #nonlocals must already exist in enclosing def!
state = 0
print(label, state)
return nested
SyntaxError: no binding for nonlocal 'state' found
>>>def tester(start):
def nested(label):
global state #Globals dont have to exits yet when declared
state = 0 #This creates the name in the module now
print(label, state)
return nested
>>> F = tester(0)
>>> F('abc')
abc 0
>>> state
0
Second, nonlocal restricts the scope lookup to just enclosing defs; nonlocals are not looked up in the enclosing module's global scope or the built-in scope outside all def's, even if they are already there:
for example:-
>>>spam = 99
>>>def tester():
def nested():
nonlocal spam #Must be in a def, not the module!
print('current=', spam)
spam += 1
return nested
SyntaxError: no binding for nonlocal 'spam' found
These restrictions make sense once you realize that python would not otherwise generally know enclosing scope to create a brand-new name in. In the prior listing, should spam be assigned in tester, or the module outside? Because this is ambiguous, Python must resolve nonlocals at function creation time, not function call time.
The answer is that the global scope does not enclose anything - it is global to everything. Use the global keyword in such a case.
Historical reasons
In 2.x, nonlocal didn't exist yet. It wasn't considered necessary to be able to modify enclosing, non-global scopes; the global scope was seen as a special case. After all, the concept of a "global variable" is a lot easier to explain than lexical closures.
The global scope works differently
Because functions are objects, and in particular because a nested function could be returned from its enclosing function (producing an object that persists after the call to the enclosing function), Python needs to implement lookup into enclosing scopes differently from lookup into either local or global scopes. Specifically, in the reference implementation of 3.x, Python will attach a __closure__ attribute to the inner function, which is a tuple of cell instances that work like references (in the C++ sense) to the closed-over variables. (These are also references in the reference-counting garbage-collection sense; they keep the call frame data alive so that it can be accessed after the enclosing function returns.)
By contrast, global lookup works by doing a chained dictionary lookup: there's a dictionary that implements the global scope, and if that fails, a separate dictionary for the builtin scope is checked. (Of course, writing a global only writes to the global dict, not the builtin dict; there is no builtin keyword.)
Theoretically, of course, there's no reason why the implementation of nonlocal couldn't fall back on a lookup in the global (and then builtin) scope, in the same way that a lookup in the global scope falls back to builtins. Stack Overflow is not the right place to speculate on the reason behind the design decision. I can't find anything relevant in the PEP, so it may simply not have been considered.
The best I can offer is: like with local variable lookup, nonlocal lookup works by determining at compile time what the scope of the variable will be. If you consider builtins as simply pre-defined, shadow-able globals (i.e. the only real difference between the actual implementation and just dumping them into the global scope ahead of time, is that you can recover access to the builtin with del), then so does global lookup. As they say, "simple is better than complex" and "special cases aren't special enough to break the rules"; so, no fallback behaviour.
I have a very simple and maybe dumb question:
Why does this work?
def print_list():
for student in student_list:
print(student)
student_list = ["Simon", "Mal", "River", "Zoe", "Jane", "Kaylee", "Hoban"]
print_list()
The way I've come to know functions and arguments, the function print_list() shouldn't recognize student_list since I didn't assign it as an argument for the function.
By the time you're calling print_list(), you have student_list defined as a global variable.
In Python, variables are created when you assign them. In your case, student_list is assigned in the global scope, so it is a global variable. (The global scope is the stuff that isn't inside your function.)
When Python encounters a variable inside a function that is not a local variable (that is, it was not passed in as an argument and was not assigned inside the function), it automatically looks for the variable in the global scope.
If you are wondering what the purpose of the global statement is, since global variables are already visible inside functions: global allows you to reassign a global variable, and have it take effect globally. For example:
def b():
global a
a = 5
a = 4
print(a) # prints 4
b()
print(a) # prints 5
In most cases, you don't need the global statement, and I would recommend that you don't use it, especially until you are much more experienced in Python. (Even experienced Python programmers tend not to use global very much, though.)
The way I understand it is that your program has 3 parts
define print_list()
initialise student_list (global variable)
call print_list()
When you call print_list(), student_list is already there. Also, in a function you have the scopes where a variable (student_list) is searched:
1. local scope (it'll fail because you don't have it defined, only referred)
2. global scope (it'll succeed, because it was just initialised