save variable to interactive namespace from python debugger

前端 未结 1 1666
挽巷
挽巷 2020-12-17 04:55

When I am running inside an interactive session (in my case ipython), and am currently inside a debugger (ipdb or pdb) I would like to

相关标签:
1条回答
  • 2020-12-17 05:25

    You can accomplish this by getting a reference to the outer interpreter's stack frame, and writing to its frame globals.

    Given a sample module with a breakpoint that kicks us into pdb:

    my_module.py:

    def fun(arg):
        import pdb; pdb.set_trace()
        print arg
    

    Example demonstrating the basic concept:

        >>> import my_module
        >>> my_module.fun(1)
        > /Users/lukasgraf/src/stackoverflow/my_module.py(3)fun()
        -> print arg
        (Pdb) import sys
        (Pdb) sys._getframe(0)
        <frame object at 0x1032ab290>
        # this is the current frame
    
        (Pdb) sys._getframe(0).f_globals['__name__']
        'my_module'
    
        # Next outer frame
        (Pdb) sys._getframe(1).f_globals['__name__']
        'pdb'
    
        # etc...
    
        # In this example, frame 10 happens to be
        # the one from the outer interpreter
        (Pdb) sys._getframe(10).f_globals['__name__']
        '__main__'
    

    So here's a quick and dirty function that walks up the stack looking for '__name__' with a value of '__main__' in frame globals:

    debughelper.py:

    import sys
    
    # Be safe and define a maximum of frames we're trying to walk up
    MAX_FRAMES = 20
    
    def save_to_interactive(dct):
        n = 0
        # Walk up the stack looking for '__name__'
        # with a value of '__main__' in frame globals
        for n in range(MAX_FRAMES):
            cur_frame = sys._getframe(n)
            name = cur_frame.f_globals.get('__name__')
            if name == '__main__':
                # Yay - we're in the stack frame of the interactive interpreter!
                # So we update its frame globals with the dict containing our data
                cur_frame.f_globals.update(dct)
                break
    

    Usage:

    >>> import my_module
    >>> my_module.fun('foo')
    > /Users/lukasgraf/src/stackoverflow/my_module.py(3)fun()
    -> print arg
    (Pdb) import debughelper
    (Pdb) debughelper.save_to_interactive({'mykey': 42})
    (Pdb) c
    foo
    # We continued PDB, so we're in the outer interpreter again
    >>> print mykey
    42
    >>>
    
    0 讨论(0)
提交回复
热议问题