1

For Python 3. I want to call a nested function from a top-level function. NOT access a variable in a nested function but call a nested function (what I'd normally refer to as a subroutine) from a "parent" function.

Answers on SO and elsewhere describe how to use the global and nonlocal keywords to enable variables in nested functions to be accessed by "parent" functions. But I haven't been able to translate that technique to Python 3 nested functions.

What I'm hoping to achieve, largely for outer-to-inner readability, is:

def topLevelFunction(listOfStrings):
    # Top-level function's code here.
    desiredValue = nestedFunction(dataToModify)
    return(desiredResult)

    # This nested function's source code is visibly contained within its parent.
    def nestedFunction(oneListEntry):
        # Modify data passed to function.
        return(fixedData)

This structure of course produces UnboundLocalError: local variable 'nestedFunction' referenced before assignment.

I've circumvented that with:

def topLevelFunction(listofStrings):
    def nestedFunction(oneListEntry):
        # nestedFunction's code goes here.
        return(fixedData)

    # topLevelFunction's code goes here.
    # Only in this "upside down" structure can top-level function call nestedFunction?
    return(desiredResult)

Part of the problem seems to be that the nonlocal / global keywords that enable me to reference variables outside of nested functions' scope haven't enabled me to do the same thing for nested functions themselves(?) Or if they do, the syntax is unique? If that's the case, thanks for a pointer to that specific syntax.

I've also made nestedFunction a stand-alone function at the same level / scope as topLevelFunction. But at least from a readability perspective both circumventions (I won't call them fixes) seem to require me to write "upside down" code where things that are used later in the program flow must be "higher" in the source code?

Perhaps I'm too accustomed to compiled languages that don't require this? Or must I instead create a Python 3 class?

RBV
  • 1,367
  • 1
  • 14
  • 33
  • You need to define the function before it can be called. – iBug Apr 18 '18 at 02:59
  • So in other words what I perceive as "upside down" source code is the correct way to do this in Python 3? Or is there some way to "pre-define" the function name so that the code can be written like my first example? – RBV Apr 18 '18 at 03:10
  • I think you need to define the whole body of the function before you call it for the first time. – iBug Apr 18 '18 at 03:54
  • 1
    Your second "circumvention" would work: define `nestedFunction` after defining `topLevelFunction`. As @iBug and https://stackoverflow.com/a/758197/500207 explain, you can define variables (functions are just variables that can be `__call__`ed) wherever you want, so long as when the Python VM's execution reaches some code, all variables have to be defined. Which is why the inner nesting fails. But which is also why defining both in the same scope will work. – Ahmed Fasih Apr 18 '18 at 04:29
  • Yeah, I have it working using the second structure. But I really hate reading the source code. The logical flow seems tangled / upside-down. It seems like a Python "trick" that one needs to know that one can't grasp the code's logic from top to bottom but rather from inside out... – RBV Apr 18 '18 at 15:50

0 Answers0