From the Python FAQ, we can read :
In Python, variables that are only referenced inside a function are implicitly global
And from the Python Tutorial on defining functions, we can read :
The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names
Now I perfectly understand the tutorial statements, but then saying that variables that are only referenced inside a function are implicitly global
seems pretty vague to me.
Why saying that they are implicitly global if we actually start looking at the local symbol tables, and then follow with the more 'general' ones? Is it just a way of saying that if you're only going to reference a variable within a function, you don't need to worry if it's either local or global
?
The reason global variables are bad is that they enable functions to have hidden (non-obvious, surprising, hard to detect, hard to diagnose) side effects, leading to an increase in complexity, potentially leading to Spaghetti code.
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.
In Python, global keyword allows you to modify the variable outside of the current scope. It is used to create a global variable and make changes to the variable in a local context.
Global variables are dangerous because they can be simultaneously accessed from multiple sections of a program. This frequently results in bugs.
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.
The global variable with the same name will remain as it was, global and with the original value. Normally, when you create a variable inside a function, that variable is local, and can only be used inside that function.
Global variables can be used by everyone, both inside of functions and outside. If you create a variable with the same name inside a function, this variable will be local, and can only be used inside the function.
In languages that default to passing by value, you may find performance benefits from passing the variable by reference instead, especially when the variable holds a lot of data. This will be more apparent when your code is running on resource-constrained machines. In Python, however, this is never a problem.
(See further down for a summary)
What this means is that if a variable is never assigned to in a function's body, then it will be treated as global.
This explains why the following works (a
is treated as global):
a = 1
def fn():
print a # This is "referencing a variable" == "reading its value"
# Prints: 1
However, if the variable is assigned to somewhere in the function's body, then it will be treated as local for the entire function body .
This includes statements that are found before it is assigned to (see the example below).
This explains why the following does not work. Here, a
is treated as local,
a = 1
def fn():
print a
a = 2 # <<< We're adding this
fn()
# Throws: UnboundLocalError: local variable 'a' referenced before assignment
You can have Python treat a variable as global with the statement global a
. If you do so, then the variable will be treated as global, again for the entire function body.
a = 1
def fn():
global a # <<< We're adding this
print a
a = 2
fn()
print a
# Prints: 1
# Then, prints: 2 (a changed in the global scope too)
Unlike what you might expect, Python will not fall back to the global scope it if fails to find a
in the local scope.
This means that a variable is either local or global for the entire function body: it can't be global and then become local.
Now, as to whether a variable is treated as local or global, Python follows the following rule. Variables are:
global
statement is usedglobal
was not used)In fact, "implicitly global" doesn't really mean global. Here's a better way to think about it:
So, if a variable is "implicitly global" (== "outside the function"), then its "enclosing scope" will be looked up first:
a = 25
def enclosing():
a = 2
def enclosed():
print a
enclosed()
enclosing()
# Prints 2, as supplied in the enclosing scope, instead of 25 (found in the global scope)
Now, as usual, global
lets you reference the global scope.
a = 25
def enclosing():
a = 2
def enclosed():
global a # <<< We're adding this
print a
enclosed()
enclosing()
# Prints 25, as supplied in the global scope
Now, if you needed to assign to a
in enclosed
, and wanted a
's value to be changed in enclosing
's scope, but not in the global scope, then you would need nonlocal
, which is new in Python 3. In Python 2, you can't.
Python’s name-resolution scheme is sometimes called the LEGB rule, after the scope names.
When you use an unqualified name inside a function, Python searches up to four scopes—the local (L) scope, then the local scopes of any enclosing (E) defs and lambdas, then the global (G) scope, and then the built-in (B) scope—and stops at the first place the name is found. If the name is not found during this search, Python reports an error.
In other words, all names assigned inside a function def
statement (or a lambda
) are locals by default. Functions can freely use names assigned
in syntactically enclosing functions and the global scope, but they must declare
such nonlocals
and globals
in order to change them.
Reference: http://goo.gl/woLW0F
This is confusing and the documentation could stand to be more clear.
"referenced" in this context means that a name is not assigned to but simply read from. So for instance while a = 1
is assignment to a
, print(a)
(Python 3 syntax) is referencing a
without any assignment.
If you reference a
as above without any assignment, then the Python interpreter searches the parent namespace of the current namespace, recursively until it reaches the global namespace.
On the other hand, if you assign to a variable, that variable is only defined inside the local namespace unless declared otherwise with the global
keyword. So a = 1
creates a new name, a
, inside the local namespace. This takes precedence over any other variable named a
in higher namespaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With