0

I am trying to learn Python and have few doubts with .r.t to multi-level nested functions and function closures in Python. Please help me understand how will this work.

Questions from the code below:

  1. How can I call func3 from main block ?
  2. Will func3 have access to x1 from func1 or just x2 from the immediate enclosing scope of func2 ?.

Sample code:

# File: nesteFunc.py
def func1():
    x1 = 1
    def func2():
        x2 = 2
        def func3():
            x3 = 3
            print(x1, x2, x3)
        return func3

if __name__ == "__main__":
    f = func1()
    f()            # line 14

The code above gives me this error message:

Traceback (most recent call last):
  File "D:/Python Prep/nestedFunc", line 14, in <module>
    f()
TypeError: 'NoneType' object is not callable

Process finished with exit code 1
5
  • 2
    func1 does not return a function object, so calling func1() will return None to variable f. And f() raise TypeError. Commented Mar 28, 2016 at 13:15
  • 2
    At the bottom of func1 put return func2 then you can do f2 = func1(); f3 = f2(); f3(). Or do something more sane. Commented Mar 28, 2016 at 13:16
  • Not sure why you would need this in Python, but this generally gives non-pythonic, un-maintainable code. Commented Mar 28, 2016 at 13:20
  • Adding "return func2" at the end of func1 works. Thanks for the reply. Commented Mar 28, 2016 at 13:21
  • You did never define a function called f, so in the last line you can't call it. Commented Mar 28, 2016 at 13:25

3 Answers 3

7

func1 does return nothing (implicitly None), that is why you get the exception, if you want to call func3 from main block, just return func2, call func2 to get func3 and then call it.

# File: nesteFunc.py
def func1():
    x1 = 1
    def func2():
        x2 = 2
        def func3():
            x3 = 3
            print(x1, x2, x3)
        return func3
    return func2

if __name__ == "__main__":
    f2 = func1()
    f3 = f2()
    f3()

About your second question, yes, func3 will hace access to variables x1 and x2 because they exist in the parent scope.

Sign up to request clarification or add additional context in comments.

Comments

0

You don't need to return func2 or func3 in func1(), if it's just to print (x1, x2, x3). You could do:

# File: nesteFunc.py
def func1():
    x1 = 1
    def func2():
        x2 = 2
        def func3():
            x3 = 3
            print(x1, x2, x3)
        func3()
    func2()

if __name__ == "__main__":
    func1()

Comments

0
def arith():
    def add(a):
        x=a+5
        print(x)
        def sub(b):
            y=b-5
            print(y)
            def mul(c):
                z=c*5
                print(z)
            return mul
        return sub
    return add
arith()(10)(10)(10)

1 Comment

While this code might show an example of a multi-level nested function call, it looks quite complicated. Could you consider appending the answer with a short explanation on how this code works?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.