12

I recently came across the idea of defining a function within a function in Python. I have this code and it gives this error:


def f1(a):
    def f2(x):
       return a+x
    return 2*a

Error: On calling f2(5)

Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
f2(5)
NameError: name 'f2' is not defined

I am having some difficulty understanding the way global variables are used across functions or even in recursive calls. I would really appreciate it if someone would point out my mistake and maybe help me along the way. Thanks!!

Community
  • 1
  • 1
OneMoreError
  • 7,518
  • 20
  • 73
  • 112

2 Answers2

12

You defined f2 in the local namespace of f1 only; it is not available globally.

If you want such a nested function to be available at the module level, you'd have to either return it from the function, or define a global variable to store it in:

def f1(a):
    def f2(x):
       return a+x
    return 2*a, f2

then call that as result, f2 = f1(somevariable_or_literal).

The global approach is not recommendable (using a global rarely is) but would look something like:

f2 = None

def f1(a):
    global f2
    def f2_local(x):
         return a+x
    f2 = f2_local
    return 2*a

at which point f2 will be set when you have called f1.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
7

f2 is defined inside f1. Therefore, it's scope only extends inside the function f1. Outside of that space, the function f2 doesn't even exist, which is why you're getting the error.

If you were to call f2 from somewhere inside f1 after f2 is defined, it would work.

Short Description of Python Scoping Rules has a good explanation of how scope works in Python.

Community
  • 1
  • 1
Collin
  • 11,977
  • 2
  • 46
  • 60