Scope rules in Python functions


Python is a statically scoped language, although it is a dynamic language itself. In other words, the scope of a variable in Python is determined by its position in the source code, which is somewhat similar to C, but the difference in scope between Python and C is still very obvious.


Next, we will talk about Python’s scope rules, and we will also explain the differences between Python and C in terms of scope.

In Python 2.0 and previous versions, Python only supports three types of scope, namely local scope, global scope, and built-in scope; in Python 2.2, Python officially introduced a new role Domain --- Nested scope; in Python 2.1, nested scope can be turned on as an option; the introduction of nested scope essentially implements support for closures in Python. Knowledge about closures, There are many explanations online, so I won’t go into details here. Correspondingly, the variable search order changes from the previous LGB to LEGB (L: Local, E: Enclosing, G: Global, B: Built-in).


In Python, not any code block can introduce a new scope, which is very different from C:


#include<stdio.h>int main() {    if(2 > 0) {        int i = 0;
    }
    printf("i = %d", i);    return 0;
}

In this code, the if clause introduces a local scope, and the variable i exists in this local scope, but It is not visible to the outside world, so the subsequent reference to variable i in the printf function will cause a compilation error.

However, this is not the case in Python:

if True:
    i = 0print i

In this code, the if clause does not introduce a local scope, and the variable i is still in in the global scope, therefore, the variable i is visible to the subsequent print statement.

In fact, in Python, only modules, classes and functions will introduce new scopes, and other code blocks will not introduce new scopes.

In Python, you do not have to pre-declare a variable before using it, but before you actually use it, it must have been bound to an object; name binding will introduce a new variable in the current scope. , while shielding variables with the same name in the outer scope, no matter where in the current scope this name binding occurs.

def f():    print i
f()


The running result will show: NameError: global name 'i' is not defined. Python first searches for variable i in the local scope of function f, and the search fails. Then it searches for variable i in the global scope and built-in scope, but still fails, and finally throws a NameError exception.

i = 0def f():
    i = 8    print i
f()print i


The running results show: 8 and 0. i = 8 is a name binding operation. It introduces a new variable i in the local scope of function f and shields the global variable i. Therefore, the print statement inside f sees the local variable i, and the print statement outside f sees the local variable i. What the statement sees is the global variable i.

i = 0def f():    print i
    i = 0
f()


The running result shows: UnboundLocalError: local variable 'i' referenced before assignment. In this example, the variable i in function f is a local variable, but when the print statement uses it, it has not been bound to any object, so an exception is thrown.

print i
i = 0


Whether it is run interactively or as a script file, the result shows: NameError: name 'i' is not defined. The output here is different from the previous example because it is in the top-level scope (module scope). For module code, the code does not undergo any preprocessing before execution, but for the function body, the code has already undergone preprocessing before running, so no matter where the name binding occurs in the scope, it will Can feel it. Although Python is a statically scoped language, name lookups do occur dynamically, so name problems are not discovered until runtime.


In Python, name binding introduces a new variable in the scope to which it belongs and binds it to an object. Name binding occurs in the following situations:


  1. Parameter declaration: Parameter declaration is in the local scope of the function Introduce new variables into;
  2. Assignment operation: The initial assignment of a variable will introduce a new variable in the current scope, and subsequent assignment operations The variable will be rebind;
  3. Class and function definition: Class and function definition introduce the class name and function name into the current scope as variables, The class body and function body will form another scope;
  4. #import statement: The import statement introduces new variables in the current scope, usually In the global scope;
  5. for statement: The for statement introduces a new variable (loop variable) in the current scope;
  6. except statement: The except statement introduces new variables (exception objects) in the current scope.


In Python, the scope introduced by the class definition is invisible to the member functions, which is very different from C or Java. Different, so in Python, if a member function wants to refer to a variable defined by the class body, it must refer to it through self or the class name.


The addition of nested scopes will cause some codes to fail to compile or obtain different running results. Here the Python interpreter will help you identify these places that may cause problems. , give a warning.


#The locals function returns all local variables, but will not return variables in nested scopes. In fact, no function will return variables in nested scopes.