The problem

num = 10
def changeNum() :
  num=20
  print(num)


changeNum() # 20
print(num)  # 10
Copy the code

In a function, modifying an external variable directly does not take effect.

The reason:

Python variable access rules:

In Python, assigning to a variable in a local scope is not associated with the global scope because it does not need to be defined before assigning to a variable. Instead, it creates a local variable in the current local scope, creating a temporary dead zone (that cannot be called before the variable is declared).

To solve

General idea: Map parent or global variables to the current local scope through keywords.

global

x=10

# local scope
def changeNum() : 
  # print(x) # SyntaxError: name 'x' is used prior to global declaration
  global x
  x = 20
  a = 'kkk'
  def changeStr() :
    global a
    a = 'bbb'

  changeStr()
  print(a) # kkk

changeNum()
print(x) # 20
print(a) # bbb
Copy the code
  1. globalKeyword, can beGlobal scopeIs mapped to the current scope, after modification, can take effect;
  2. May not be inglobalUse a variable before a word;
  3. Variables in nested functions that are not in global scope are usedglobalDon’t take effect;
  4. If there is no declared variable in the global environment, use it in the local environmentglobalAfter, the variable isThe global variableIs still accessible globally.

nonlocal

x = 10

# local scope
def changeNum() : 
  # nonlocal x # SyntaxError: no binding for nonlocal 'x' found
  x = 20
  a = 'kkk'
  b = 'ggg'
  def changeStr1() :
    nonlocal a
    a = 'bbb'

    def changeStr2() :
      nonlocal b
      b = 'ccc'

    changeStr2()

  changeStr1()
  print(a) # bbb
  print(b) # ccc

changeNum()
print(x) # 10
Copy the code
  1. nonlocalYou cannot bind globally-scoped variables;
  2. nonlocalYou can bind any ancestor in a nested functionA local variable;

nonlocalglobalThe difference between

At its core, global is the key that gives local scopes access to global variables; Nonlocal allows the underlying local scope to access local variables in the parent (grandparent) scope.