Give a detailed example to explain the difference between global and nonlocal in python

the difference

Both keywords are used to allow the use of outer variables in a local scope.

  • global means to declare the variable as global
  • nonlocal means that the variable is declared as an outer variable (local variable of the outer function, and cannot be a global variable)

principle

1. When python accesses a variable, it must first locate where the variable comes from.
The order in which python references variables is as follows:

  1. current scope local variables
  2. outer scope variable
  3. Global variables in the current module
  4. python built-in variables

That is, the variable is first searched from the local scope, if not, then go to the outer layer to find it, and if it is not found at the end, an error will be reported.

2. When python creates a new variable, the default scope is the current local scope.

Summary and Examples

1. The inner function can access the outer variable without modifying the outer variable.

a = 1
def fun():
    print(a) # 在函数内部找不到对 a 的定义,则去外层查询。输出1。
fun()

2. If the inner function modifies the outer variable of the same name, python will think that a new local variable is defined, which has nothing to do with the outer variable.

a = 1
def fun():
    a = 2 # 声明了一个局部变量,与外面等于1的那个a没有关系了
    print(a) # 输出2
fun()
print(a) # 输出1

3. If the variable name is called before the internal function modifies the global variable of the same name, Unbound-LocalError will be raised

a = 1
def fun():
    print(a) # 先引用
    a = 2 # 再修改
fun()

Error:

File “C:\Users\GongYanshang\Desktop\untitled-1.py”, line 3, in fun
print(a)
builtins.UnboundLocalError: local variable ‘a’ referenced before assignment

The error says that the local variable a is referenced before it is defined.
The key is that the error is reported on the line print(a). Combined with the first example, only a line a = 2 is added, but print(a) reports an error. This shows that before print(a), python already knows that a is a local variable and can only be searched from the local scope. Where did you know it? Known from the line a = 2.
At this time, if we want to force access to the outer variable a, we can use the global keyword:

a = 1
def fun():
    global a # a为全局变量
    print(a) # 输出1
    a = 2 # 改变的是全局变量,因此出了这个局部作用域,仍然有效
fun()
print(a) # 输出2

Note that at this time, do not replace global with the nonlocal keyword, otherwise an error will be reported:

Syntax Error: no binding for nonlocal ‘a’ found

This is because nonlocal means the outer variable, but once the outer variable is a global variable, only global can be used. If you put this code all into one function, you can use nonlocal:

def outer_fun():
    a = 1
    def fun():
        nonlocal  a # a为外层变量
        print(a) # 输出1
        a = 2
    fun()
    print(a) #输出2
outer_fun()

Similarly, if you change nonlocal to global at this time, an error will also be reported:

builtins.NameError: name ‘a’ is not defined

Note : It can be found that the previous error of changing global to nonlocal is different from the error of changing nonlocal to global this time. The former is an error in the nonlocal a line, and the latter is an error in the print(a) line. That is to say, before using nonlocal a, it must be ensured that the outer layer has indeed defined a, but when global a is used, it can be allowed that a has not been defined in the global variable, and it can be left to be defined later. For example, add the definition of a before print(a), there will be no error:

def outer_fun():
    a = 1
    def fun():
        global  a # a为全局变量,与上面等于1的 a 没有关系
        a = 3 # 定义全局变量
        print(a) # 输出3
        a = 2
    fun()
    print(a) #输出1,局部变量
outer_fun()
print(a) # 输出2,全局变量

4. As long as there is a global or nonlocal command in a scope, no matter where the command is, it is valid from the beginning to the end of the entire scope.
If you swap the positions of global a and a = 3 in the previous example, the result is exactly the same:

def outer_fun():
    a = 1
    def fun():
        a = 3 # 此时python已经知道a是全局变量了,这句话相当于定义一个全局变量a,值为3
        global  a # a为全局变量
        print(a) # 输出3
        a = 2
    fun()
    print(a) #输出1,局部变量
outer_fun()
print(a) # 输出2,全局变量

If we comment out the sentence global a, then a = 3 is a new local variable, which is actually equivalent to example 2.

def outer_fun():
    a = 1
    def fun():
        a = 3
        #global  a
        print(a) # 输出3
        a = 2
    fun()
    print(a) #输出1,fun()里面的a已经释放掉了
outer_fun()
#print(a) # 这一句也要注释掉,不然会报错,因为已经没有全局变量a了

That is to say, python does not allow the same variable name in the same local scope to have multiple roles, that is, it is not allowed to be a local variable before the sentence global a and a global variable after it. So, although python is an interpreted language and type errors are found only during execution, it does not mean that the following code will not affect the results of the previous code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325968521&siteId=291194637