DEV Community

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

Posted on

global vs nonlocal in Python (5)

Buy Me a Coffee

*Memo:

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

<Read(Intuitive version)>:

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

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

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

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

<Read(Unintuitive version)>:

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

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

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

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

<Change(Intuitive version)>:

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

num = 2 # <- ✖
class Cls1:
    num = 3 # <- ✖
    class Cls2:
        num = 4 # <- ✖
        def first(self):
            num = 5 # <- ✖
            def second():
                num = 6 # <- 〇
                def third():
                    nonlocal num # Here
                    num += 10    # Here
                    print(num) # 16
                third()
                print(num) # 16
            second()
Cls1().Cls2().first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
class Cls1:
    num = 3 # <- ✖
    class Cls2:
        num = 4 # <- ✖
        def first(self):
            num = 5 # <- 〇
            def second():
                # num = 6 # <- Commemnted
                def third():
                    nonlocal num # Here
                    num += 10    # Here
                    print(num) # 15
                third()
            second()
            print(num) # 15
Cls1().Cls2().first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

num = 2 # <- ✖
class Cls1:
    num = 3 # <- ✖
    class Cls2:
        num = 4 # <- ✖
        def first(self):
            # num = 5 # <- Commemnted
            def second():
                # num = 6 # <- Commemnted
                def third():
                    nonlocal num # SyntaxError: no binding        
                    num += 10    # for nonlocal 'num' found
                    print(num)
                third()
            second()
Cls1().Cls2().first()
Enter fullscreen mode Exit fullscreen mode

<Change(Unintuitive version)>:

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

class Cls1:
    class Cls2:
        def first(self):
            def second():
                def third():
                    nonlocal num # Here
                    num += 10    # Here
                    print(num) # 16
                num = 6 # <- 〇
                third()
                print(num) # 16
            num = 5 # <- ✖
            second()
        num = 4 # <- ✖
    num = 3 # <- ✖
num = 2 # <- ✖
Cls1().Cls2().first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

class Cls1:
    class Cls2:
        def first(self):
            def second():
                def third():
                    nonlocal num # Here
                    num += 10    # Here
                    print(num) # 15
                # num = 6 # <- Commemnted
                third()
            num = 5 # <- 〇
            second()
            print(num) # 15
        num = 4 # <- ✖
    num = 3 # <- ✖
num = 2 # <- ✖
Cls1().Cls2().first()
Enter fullscreen mode Exit fullscreen mode
""" It's from the viewpoint of `third()` """

class Cls1:
    class Cls2:
        def first(self):
            def second():
                def third():
                    nonlocal num # SyntaxError: no binding        
                    num += 10    # for nonlocal 'num' found
                    print(num)
                # num = 6 # <- Commemnted
                third()
            # num = 5 # <- Commemnted
            second()
        num = 4 # <- ✖
    num = 3 # <- ✖
num = 2 # <- ✖
Cls1().Cls2().first()
Enter fullscreen mode Exit fullscreen mode

Top comments (0)