これは、外部インタープリターのスタック フレームへの参照を取得し、そのフレーム グローバルに書き込むことで実現できます。
pdb に入るブレークポイントを持つサンプル モジュールがあるとします。
my_module.py :
def fun(arg):
import pdb; pdb.set_trace()
print arg
基本的な概念を示す例:
>>> 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__'
そこで、フレーム内グローバル'__name__'
の値を探してスタックをさかのぼる手っ取り早い汚い関数を次に示します。'__main__'
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
使用法:
>>> 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
>>>