Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python : Why is it said that variables that are only referenced are implicitly global?

Tags:

python

global

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?

like image 674
Niourf Avatar asked May 04 '14 16:05

Niourf


People also ask

What are two reasons why you should not use global variables in Python?

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.

Are all variables global 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.

Why do we use global variables in Python?

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.

Why is using the global statement a bad practice in Python?

Global variables are dangerous because they can be simultaneously accessed from multiple sections of a program. This frequently results in bugs.

Are Python variables implicitly global?

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.

What happens when you create a global variable inside a function?

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.

What is the difference between global and local variables?

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.

Is it better to pass by reference or value in Python?

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.


3 Answers

Examples

(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)

Summary

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 if only referenced and never assigned to
  • Global if the global statement is used
  • Local if the variable is assigned to at least once (and global was not used)

Further notes

In fact, "implicitly global" doesn't really mean global. Here's a better way to think about it:

  • "local" means "somewhere inside the function"
  • "global" really means "somewhere outside the function"

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.

like image 164
Thomas Orozco Avatar answered Oct 17 '22 17:10

Thomas Orozco


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.

  • Name assignments create or change local names by default.
  • Name references search at most four scopes: local, then enclosing functions (if any), then global, then built-in.
  • Names declared in global and nonlocal statements map assigned names to enclosing module and function scopes, respectively.

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

like image 41
ajknzhol Avatar answered Oct 17 '22 18:10

ajknzhol


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.

like image 1
Andrew Gorcester Avatar answered Oct 17 '22 17:10

Andrew Gorcester