python调试器中未定义所有变量

python调试器中未定义所有变量,python,python-3.x,debugging,pdb,Python,Python 3.x,Debugging,Pdb,我在Python3.6上遇到了一个非常奇怪的问题。在我的代码中间,我调用导入PDB;pdb.set_trace()调试某些代码 然后我无法正确调试,例如: (Pdb) abc = 3 (Pdb) [abc for _ in range(2)] *** NameError: name 'abc' is not defined (Pdb) [abc, abc] [3, 3] 似乎每当我使用列表理解时,都会出现变量未定义的问题。但是,如果我在打开Python之后立即调用调试器,我不会观察到这种行为,

我在Python3.6上遇到了一个非常奇怪的问题。在我的代码中间,我调用<代码>导入PDB;pdb.set_trace()调试某些代码

然后我无法正确调试,例如:

(Pdb) abc = 3
(Pdb) [abc for _ in range(2)]
*** NameError: name 'abc' is not defined
(Pdb) [abc, abc]
[3, 3]
似乎每当我使用列表理解时,都会出现变量未定义的问题。但是,如果我在打开Python之后立即调用调试器,我不会观察到这种行为,一切都会正常运行


知道我为什么会遇到这个问题吗?

之所以会出现这种情况,是因为列表理解(大部分)是在嵌套范围内进行计算的,并且在pdb中创建的嵌套范围无法访问被检查范围的局部变量。但是,它们可以访问全局,当您在打开Python后立即启动pdb时,您正在全局范围内运行它,因此您创建的
abc
是全局的

exec
和class语句中的列表理解也会发生这种情况。不幸的是,没有比“不要在那里使用列表理解”更好的解决方法了。

这是作为归档的,但作为“不会修复”关闭

根本问题正是这样说的:理解1通过定义然后运行隐藏的嵌套函数来工作,但是在框架内的pdb中定义的函数不是真正的嵌套函数,不能从框架的作用域访问变量

有一些变通方法(其中一些在b.p.o版中提到,或与该版相关的地方),但它们都只是其中一个的巧妙变体:

  • (lambda abc:[abc代表范围(2)])(abc)
    (换句话说,定义一个函数并显式地将局部值作为参数传递,而不是捕获它们。)
  • [abc_uu代表abc_uuu在[abc]代表uuu在范围(2)]
    (换句话说,使用最外层的iterable是一个参数这一事实。2)
  • [loc['abc']表示[locals()]中的loc,表示范围(2)]
    (换句话说,使用
    locals()['name']
    而不是
    name
    ,并按上述方式传递局部变量。)
  • exec
    中,使用
    exec
    以及任何已知的非常糟糕的解决方法来理解
    exec
  • 不要像用户2357112建议的那样使用理解

一,。在Python2.x中,列表理解不是这样的,只有set和dict理解以及生成器表达式。但Python3改变了列表的理解,使其与其他列表保持一致


二,。用于理解的隐藏嵌套函数几乎捕获了封闭范围中的所有名称,但最外层的iterable(第一个
中用于
的iterable)是特殊的;它实际上是隐藏函数的一个参数,表达式在封闭范围内求值并作为参数值传递。

您可以尝试以下代码:

(Pdb) !import code; code.interact(local=vars())
Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> [abc for _ in range(2)]

使用Ctrl-D返回常规pdb提示符。

类似于李潘峰的回答,但更简单的方法是在pdb中使用
交互

下面是pdb失败和
交互
在同一上下文中工作的示例

Python 3.6.3(默认,2017年10月4日06:09:05)
[GCC 4.2.1达尔文兼容苹果LLVM 8.0.0(clang-800.0.42.1)]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>def do_comp():
...   abc=3
...   进口pdb;pdb.set_trace()
...
>>>杜康普()
--返回--
>(3)do_comp()->无
(Pdb)[范围内的abc(2)]
***名称错误:未定义名称“abc”
(Pdb)互动
*互动的*
>>>[abc代表范围(2)]
[3, 3]

这是Python 3特有的吗?我没有注意到Python2的问题。@dhokas:列表理解在Python2的嵌套范围内没有计算。不过,我相信您仍然可以在Python 2中的genexps和dict/set理解中看到它。
[locals()['abc']for uuu in range(2)]
不起作用-涉及
locals()
的解决方法需要在外部范围内调用
局部变量,而不是在理解的范围内。@user2357112哦,您是对的;你需要通过一个本地口述;我会编辑。有一些方法可以执行像这样的命令<代码>求值(((lambda:x)(),vars())
这很有效!谢谢 非常感谢这个简化版本