all variables are undefined in python debugger

蓝咒 提交于 2020-01-16 18:40:09

问题


I'm facing a very strange issue on Python 3.6. In the middle of my code, I call import pdb; pdb.set_trace() to debug some code.

And then I'm not able to debug properly, for instance:

(Pdb) abc = 3
(Pdb) [abc for _ in range(2)]
*** NameError: name 'abc' is not defined
(Pdb) [abc, abc]
[3, 3]

It seems like whenever I use list comprehensions, there is an issue of variable not defined. However, if I call the debugger right after I open Python, I do not observe this behavior, everything runs fine.

Any ideas why I'm having this issue?


回答1:


This happens because list comprehensions are (mostly) evaluated in a nested scope, and nested scopes created in pdb can't access the local variables of the scope being inspected. They can access globals, though, and when you launch pdb immediately after opening Python, you're running it in a global scope, so the abc you create is global.

This also happens with list comprehensions in exec and in class statements. Unfortunately, there isn't really a better workaround than "don't use list comprehensions there".




回答2:


This is filed as b.p.o. issue #21161, but closed as "won't fix".

The root issue is exactly what user2357112's answer says: Comprehensions1 work by defining and then running a hidden nested function, but functions defined in pdb inside a frame aren't real nested functions and can't access variables from the frame's scope.

There are workarounds (some of which are mentioned in the b.p.o issue, or places linked from that issue), but they're all just clever variations on one of these:

  • (lambda abc: [abc for _ in range(2)])(abc) (In other words, define a function and explicitly pass the locals' values as arguments instead of capturing them.)
  • [abc_ for abc_ in [abc] for _ in range(2)] (In other words, use the fact that the outermost iterable is an argument.2)
  • [loc['abc'] for loc in [locals()] for _ in range(2)] (In other words, use locals()['name'] instead of name, and get the locals passed as above.)
  • Use exec plus any of the known just-as-horrible workarounds for comprehensions in exec.
  • Don't use a comprehension, as user2357112 suggests.

1. In Python 2.x, this is not true for list comprehensions, only set and dict comprehensions and generator expressions. But Python 3 changed list comprehensions to make them consistent with the others.

2. The hidden nested function for a comprehension captures almost all names from the enclosing scope—but the outermost iterable (the one in the first for) is special; it's actually a parameter to the hidden function, and the expression is evaluated in the enclosing scope and passed as the argument value.




回答3:


You could try the following code:

(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)]

Use Ctrl-D to return to the regular pdb prompt.




回答4:


Similar to Panfeng Li's answer, but a simpler way to do this is to use interact in pdb.

What follows is an example of pdb failing and interact working in the same context.

Python 3.6.3 (default, Oct  4 2017, 06:09:05)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def do_comp():
...   abc = 3
...   import pdb; pdb.set_trace()
...
>>> do_comp()
--Return--
> <stdin>(3)do_comp()->None
(Pdb) [abc for _ in range(2)]
*** NameError: name 'abc' is not defined
(Pdb) interact
*interactive*
>>> [abc for _ in range(2)]
[3, 3]


来源:https://stackoverflow.com/questions/51903399/why-am-i-getting-a-nameerror-in-list-comprehension-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!