如何在当前命名空间中获得Python交互式控制台



我想让我的Python代码在运行代码的过程中使用类似code. interaction()的东西启动一个Python交互式控制台(REPL)。但是,由code. interaction()启动的控制台看不到当前名称空间中的变量。我该怎么做:

mystring = "你好"

code.interact ()

…然后在启动的交互式控制台中,我应该能够输入mystring并得到"hello"。这可能吗?我需要将code. interaction()的"local"参数设置为什么吗?它会被设置成什么?它应该怎么叫呢?

尝试:

code.interact(local=locals())

对于调试,我通常使用

from pdb import set_trace; set_trace()

it may help

另一种方法是启动调试器,然后运行interact:

import pdb
pdb.set_trace()

然后从调试器:

(Pdb) help interact
interact
        Start an interactive interpreter whose global namespace
        contains all the (global and local) names found in the current scope.
(Pdb) interact
*interactive*
>>>

对于Python 3.10.0:

code.InteractiveConsole(locals=locals()).interact()

查看Python文档了解更多细节

如何改变全局变量()和局部变量()

不幸的是,code.interact不允许您从当前命名空间传递globals()locals(),除非您将它们复制到像code.interact(local={**globals(), **locals()})一样的单个字典中,但随后您对globals()locals()所做的更改将不会被持久化。

但是你可以通过子类化控制台并覆盖它的runcode方法来解决这个问题:

import code
try:
    import readline
except ImportError:
    pass
class MyInteractiveConsole(code.InteractiveConsole):
    """Extends InteractiveConsole to also pass globals to exec."""
    def __init__(self, globals, *args, **kwargs):
        code.InteractiveConsole.__init__(self, *args, **kwargs)
        self.globals = globals
    def runcode(self, code):
        try:
            exec(code, self.globals, self.locals)
        except SystemExit:
            raise
        except:
            self.showtraceback()

在某处定义了它之后,您可以像code.interact:

一样使用它:
MyInteractiveConsole(globals(), locals()).interact()

除了这将允许你读取和改变全局变量和局部变量:

  • x = 7将设置本地
  • global x; x = 7将设置全局

,当你用Ctrl+D(或Ctrl+Z然后在Windows上输入)离开交互式控制台时,你所做的更改应该保留在你的globals()locals()中。

警告: locals()的文档警告:

这个字典的内容不应该被修改;解释器所使用的局部变量和自由变量的值不会受到影响。

所以不要依赖locals()的这些突变来处理任何关键任务。PEP 558和PEP 667更详细,并且可能使locals()在未来的Python版本中表现得更一致。

最新更新