pythonipythonprofilerline-profiler

How can I do %lprun work on nested function in python?


In jupyter Notebook, I am trying to use %lprun on nested functions but I do not sucess.

The following code, in a notebook cell

def outerfoo():
    def innerfoo():
        print("Hello World")
        print("Good Bye")
    innerfoo()

%lprun -f outerfoo().innerfoo outerfoo()

outputs the messages (Hello World and GoodBye) but after I have this error :
UsageError: Could not find function 'outerfoo().innerfoo'.
AttributeError: 'NoneType' object has no attribute 'innerfoo'

And this one,

def outerfoo():
    def innerfoo():
        print("Hello World")
        print("Good Bye")
    %lprun -f innerfoo innerfoo()


outerfoo()

does not print messages and gives this error :
UsageError: Could not find function 'innerfoo'. NameError: name 'innerfoo' is not defined

How is it possible to profile innerfoo ?


Solution

  • I don't think you can use notebook magic inside of actual Python code, so using %lprun inside of a function block will likely never work. Instead you can store a global reference to your local function, then lprun that:

    ref = None
    def outerfoo():
        global ref
        def innerfoo():
            print("Hello World")
            print("Good Bye")
        innerfoo()
        ref = innerfoo
    
    # Must be called for `ref` to exist.
    outerfoo()
    
    %lprun -f ref ref()
    

    But all of this feels very icky. You probably shouldn't be creating nested functions in the first place.