DEV Community

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

Posted on • Edited on

global vs nonlocal in Python (1)

Buy Me a Coffee

*Memos:

With 3 functions, there are 3 kinds of variables from the viewpoint of third() as shown below:

  • 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.
""" It's from the viewpoint of `third()` """

num = 2 # <- Global variable
print(num) # 2
def first():
    num = 3 # <- Non-local variable
    print(num) # 3
    def second():
        num = 4 # <- Non-local variable
        print(num) # 4
        def third():
            num = 5 # <- Local variable
            print(num) # 5
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode

A global statement can refer to a global variable as shown below. *The doc explains the rules for local and global variables in Python:

<Read>:

""" It's from the viewpoint of `third()` """

num = 2 # <- 〇
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            global num # Here
            print(num) # 2
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

# num = 2 # <- Commented
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            global num # NameError: name 'num' is not defined.
            print(num) # Did you mean: 'sum'?
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode

<Change>:

""" It's from the viewpoint of `third()` """

num = 2 # <- 〇
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            global num # Here
            num += 10  # Here
            print(num) # 12
        third()
    second()
first()
print(num) # 12
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

# num = 2 # <- Commented
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            global num # NameError: name 'num' is not defined.
            num += 10  # Did you mean: 'sum'?
            print(num)
        third()
    second()
first()
print(num)
Enter fullscreen mode Exit fullscreen mode

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

<Read>:

""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- 〇
        def third():
            nonlocal num # Here
            print(num) # 4
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- 〇
    def second():
        # num = 4 # <- Commented
        def third():
            nonlocal num # Here
            print(num) # 3
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    # num = 3 # <- Commented
    def second():
        # num = 4 # <- Commented
        def third():
            nonlocal num # SyntaxError: no binding
            print(num)   # for nonlocal 'num' found
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode

<Change>:

""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- 〇
        def third():
            nonlocal num # Here
            num += 10    # Here
            print(num) # 14
        third()
        print(num) # 14
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- 〇
    def second():
        # num = 4 # <- Commented
        def third():
            nonlocal num # Here
            num += 10    # Here
            print(num) # 13
        third()
        print(num) # 13
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    # num = 3 # <- Commented
    def second():
        # num = 4 # <- Commented
        def third():
            nonlocal num # SyntaxError: no binding
            num += 10    # for nonlocal 'num' found
            print(num)
        third()
        print(num) 
    second()
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:

<Read>:

""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- 〇
        def third():
            print(num) # 4
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- 〇
    def second():
        # num = 4 # <- Commented
        def third():
            print(num) # 3
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- 〇
def first():
    # num = 3 # <- Commented
    def second():
        # num = 4 # <- Commented
        def third():
            print(num) # 2
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

# num = 2 # <- Commented
def first():
    # num = 3 # <- Commented
    def second():
        # num = 4 # <- Commented
        def third():
            print(num) # NameError: name 'num' is not defined.
        third()        # Did you mean: 'sum'?
    second()
first()
Enter fullscreen mode Exit fullscreen mode

<Change>:

""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            num += 10  # UnboundLocalError: cannot access local variable
            print(num) # 'num' where it is not associated with a value
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode

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

""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            global num # SyntaxError: name 'num' is nonlocal and global
            nonlocal num
            print(num)
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
def first():
    num = 3 # <- ✖
    def second():
        num = 4 # <- ✖
        def third():
            nonlocal num # SyntaxError: name 'num' is nonlocal and global
            global num
            print(num)
        third()
    second()
first()
Enter fullscreen mode Exit fullscreen mode

Top comments (0)