I am a beginner in Python, just encountered 'global' keyword recently. I understand the basic usage that 'global' changes the scope of a variable, but I wonder why the following code doesn't work:
def foo():
global y
print('y inside foo is', y)
foo()
print('global y is', y)
I would assume it outputs some empty variable like None, however it gives:
NameError: name 'y' is not defined
I've tried:
def foo():
global y
y = 1
print('y inside foo is', y)
foo()
print('global y is', y)
This gives:
y inside foo is 1
global y is 1
which is expected because we first declare there is a global variable y, and then assign 1 to it, so we find it in the globals().
Another side question is:
def foo():
def bar():
print(locals())
print(y)
y = 1
bar()
foo()
gives:
{'y': 1}
1
because inside bar(), we have one local variable 'y'.
But the local variable 'y' just disappears when I change it to:
def foo():
def bar():
print(locals())
y = y + 1
print(y)
y = 1
bar()
foo()
print(locals()) outputs {}, I don't understand why.
You never define y
to actually contain a value. In Python, trying to access a variable that has no value throws a NameError
, which you are seeing here. You could initialize your variable to start (with None
or some other preferred default value), and then use it through the rest of the file, like so:
y = None
def foo():
global y
print('y inside foo is', y)
foo()
print('global y is', y)
y inside foo is None
global y is None
example 1: What is an "empty variable" in Python? You never defined y
; you got smacked.
example 2: You understand
example 3: No, bar
does not have a local variable y
. Since there is none, it searches outward through its context stack, and finds y
in the next name space, foo
.
example 4: locals
is, indeed, empty. y
is local to foo
, not to bar
. However, your increment statement faults because the attempt to change y
implies that you have either a global y
(you do not), or you're defining a new one. Thus, the RHS y
must be local -- but is as yet undefined, and you get smacked again.
Every thing happen when Python create the function it scans it's body:
def foo():
def bar():
print(locals()) # P is not present
print(y)
print(y)
x = 5
print(locals()) # after initializing x is added to local
y = 1
p = 1
# ('x',) local variables
print(bar.__code__.co_varnames)
# ('y',) non local variables used by the function
print(bar.__code__.co_freevars)
bar()
foo()
Python found that bar
used y
but it's not initialized in any point in the body function so it's co_freevars
:
co_freevars: tuple of names of free variables (referenced via a function's closure
other variable that are are on left side of an assiegnment expression are co_varnames
co_varnames: tuple of names of arguments and local variables
When you use global you are telling Python that this is not a local variable, and when you change it's value you change it in the global space where the function is defined not where it's called.
def foo():
global y # assumes that y exist in the current module
y = 5 # when you change it's value it change the value of y in the current module
# even that we used `y` in a left side of assignment expression is not added as local variable
print(foo.__code__.co_varnames)
when you define foo
in a module that don't define a variable y
, foo
will not find that variable in the global scope of that module and this why you get: NameError: name 'y' is not defined
.
To understand more the role global
keyword check this:
def foo():
global y
y = 1 # this set the variable in the scope of module not the scope of this function
print('y' in locals()) # False it's not a local variable of this method
print('y' in globals()) # False
foo()
print('y' in globals()) # True
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.