DEV Community

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

Posted on

global vs nonlocal in Python (8)

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

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

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

<Read(Unintuitive version)>:

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

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

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

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

<Change(Intuitive version)>:

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

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

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

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

<Change(Unintuitive version)>:

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

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

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

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

Top comments (0)