DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on

global vs nonlocal in Python (10)

Buy Me a Coffee

*Memo:

With 2 functions or generators, there are 3 kinds of variables from the viewpoint of second() as shown below:

*Memo:

  • A global variable is the variable out of any functions and classes.
  • A non-local variable is the variable within outer functions.
  • A local variable is the variable which is within its function.
  • A global and non-local variable can be accessed from a function or generator as long as the function or generator is called and run after them even if the function or generator is defined before them.

<Function>:

""" It's from the viewpoint of `second()` """ def first(): def second(): v = 4 # <- local variable  print(v) # 4  return 3 v = second # <- Non-local variable  print(v()) # 3  return 2 v = first # <- Global variable print(v()) # 2 
Enter fullscreen mode Exit fullscreen mode

<Generator>:

""" It's from the viewpoint of `second()` """ def first(): def second(): v = 4 # <- local variable  print(v) # 4  yield 3 v = second() # <- Non-local variable  print(next(v)) # 3  yield 2 v = first() # <- Global variable print(next(v)) # 2 
Enter fullscreen mode Exit fullscreen mode

A global statement can refer to a global variable as shown below:

*Memo:

  • The doc explains the rules for local and global variables in Python.

<Function>:

Read:

""" It's from the viewpoint of `second()` """ def first(): def second(): global v print(v.__name__) # first  v = second # <- ✖  v() print(v.__name__) # second v = first # <- 〇 v() print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Change:

""" It's from the viewpoint of `second()` """ def first(): def second(): global v v.__name__ = 'Hello' print(v.__name__) # Hello  v = second # <- ✖  v() print(v.__name__) # second v = first # <- 〇 v() print(v.__name__) # Hello 
Enter fullscreen mode Exit fullscreen mode

<Generator>:

Read:

""" It's from the viewpoint of `second()` """ def first(): def second(): global v print(v.__name__) # first  yield v = second() # <- ✖  next(v) print(v.__name__) # second  yield v = first() # <- 〇 next(v) print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Change:

""" It's from the viewpoint of `second()` """ def first(): def second(): global v v.__name__ = 'Hello' print(v.__name__) # Hello  yield v = second() # <- ✖  next(v) print(v.__name__) # second  yield v = first() # <- 〇 next(v) print(v.__name__) # Hello 
Enter fullscreen mode Exit fullscreen mode

A nonlocal statement can refer to a non-local variable as shown below:

<Function>:

Read:

""" It's from the viewpoint of `second()` """ def first(): def second(): nonlocal v print(v.__name__) # second  v = second # <- 〇  v() print(v.__name__) # second v = first # <- ✖ v() print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Change:

""" It's from the viewpoint of `second()` """ def first(): def second(): nonlocal v v.__name__ = 'Hello' print(v.__name__) # Hello  v = second # <- 〇  v() print(v.__name__) # Hello v = first # <- ✖ v() print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

<Generator>:

Read:

""" It's from the viewpoint of `second()` """ def first(): def second(): nonlocal v print(v.__name__) # second  yield v = second() # <- 〇  next(v) print(v.__name__) # second  yield v = first() # <- ✖ next(v) print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Change:

""" It's from the viewpoint of `second()` """ def first(): def second(): nonlocal v v.__name__ = 'Hello' print(v.__name__) # Hello  yield v = second() # <- 〇  next(v) print(v.__name__) # Hello  yield v = first() # <- ✖ next(v) print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Without a global or nonlocal statement, the closest non-local variable or a global variable can be referred to in order as shown below:

<Function>:

Read:

""" It's from the viewpoint of `second()` """ def first(): def second(): print(v.__name__) # second  v = second # <- 〇  v() print(v.__name__) # second v = first # <- ✖ v() print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Change:

""" It's from the viewpoint of `second()` """ def first(): def second(): v.__name__ = 'Hello' print(v.__name__) # Hello  v = second # <- 〇  v() print(v.__name__) # Hello v = first # <- ✖ v() print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

<Generator>:

Read:

""" It's from the viewpoint of `second()` """ def first(): def second(): print(v.__name__) # second  yield v = second() # <- 〇  next(v) print(v.__name__) # second  yield v = first() # <- ✖ next(v) print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Change:

""" It's from the viewpoint of `second()` """ def first(): def second(): v.__name__ = 'Hello' print(v.__name__) # Hello  yield v = second() # <- 〇  next(v) print(v.__name__) # Hello  yield v = first() # <- ✖ next(v) print(v.__name__) # first 
Enter fullscreen mode Exit fullscreen mode

Using both a global and nonlocal statement in the same function or generator gets error as shown below:

<Function>:

""" It's from the viewpoint of `second()` """ def first(): def second(): global v # SyntaxError: name 'v' is nonlocal and global  nonlocal v print(v.__name__) v = second # <- ✖  v() print(v.__name__) v = first # <- ✖ v() print(v.__name__) 
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `second()` """ def first(): def second(): nonlocal v # SyntaxError: name 'v' is nonlocal and global  global v print(v.__name__) v = second # <- ✖  v() print(v.__name__) v = first # <- ✖ v() print(v.__name__) 
Enter fullscreen mode Exit fullscreen mode

<Generator>:

""" It's from the viewpoint of `second()` """ def first(): def second(): global v # SyntaxError: name 'v' is nonlocal and global  nonlocal v print(v.__name__) yield v = second() # <- ✖  next(v) print(v.__name__) yield v = first() # <- ✖ next(v) print(v.__name__) 
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `second()` """ def first(): def second(): nonlocal v # SyntaxError: name 'v' is nonlocal and global  global v print(v.__name__) yield v = second() # <- ✖  next(v) print(v.__name__) yield v = first() # <- ✖ next(v) print(v.__name__) 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)