我注意到将pdb.set_trace()
或ipdb.set_trace()
作为上下文的最后一行运行,其上下文管理器和由它分配的变量已被破坏。
特别是,当使用Python的内置open()
进行相同操作时,情况并非如此。
import pdb
import contextlib
@contextlib.contextmanager
def my_open(filename):
with open(filename) as f:
yield f
class my_open_class():
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.f = open(self.filename)
return self.f
def __exit__(self, exc_type, exc_value, exc_traceback):
self.f.close()
with open("/dev/null") as f:
# f will be available
pdb.set_trace()
with my_open("/dev/null") as f:
# f will not be available!
pdb.set_trace()
with my_open_class("/dev/null") as f:
# f will not be available!
pdb.set_trace()
with my_open("/dev/null") as f:
# f will be available!
pdb.set_trace()
pass
with my_open_class("/dev/null") as f:
# f will be available!
pdb.set_trace()
pass
在运行并逐步执行代码时(使用c
从第一个断点到第二个断点),提示也不同:
在open(...)
中输入上下文时,第一个块停止
> /Users/me/test.py(28)<module>()
-> with my_open("/dev/null") as f:
当第二个和第三个块在__exit__(...)
处离开上下文时停止
(Pdb) c
--Call--
> /usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py(86)__exit__()
-> def __exit__(self, type, value, traceback):
(Pdb) c
--Call--
> /Users/me/test.py(19)__exit__()
-> def __exit__(self, exc_type, exc_value, exc_traceback):
第四个和第五个块停在pass
:
(Pdb) c
> /Users/me/test.py(41)<module>()
-> pass
(Pdb) c
> /Users/me/test.py(47)<module>()
-> pass
(Pdb) c
我找不到这种行为的原因,也无法相信这是故意的。
这是Python还是pdb中的错误?有没有办法在不添加pass
的情况下规避这一问题?