在 Python 模块的上下文中执行 REPL 代码而不是__main__?



我有一个Python实例,打开了一个REPL并导入了几个模块。我可以像运行这些模块之一一样运行代码吗?

示例:my.module 包含类似

some_module_var = 123
def my_function():
return 7

我希望能够打字

new_module_var = my_function(some_module_var)

以某种形式进入 REPL 并让它像模块的一部分一样执行,而不是

my.module.new_module_var = my.module.my_function(my.module.some_module_var)

有没有一个很好的解决方案?

我已经尝试过的一件事是

exec(compile("my_function(some_module_var)", "<fake_file>", "exec"),
my.module, {})

将模块作为全局命名空间,但显然,命名空间不能是模块。

此外,作为一种解决方法,我们可以将每个符号从模块复制到全局命名空间,运行 eval,然后复制回更改......不过,它感觉并不像Common Lisp的"只需切换REPL包"解决方案那样优雅。

或者是否有可以做到这一点的自定义 REPL?

(...我的目标是能够将整个函数发送到正在运行的 Python 实例,并让它们显示在正确的模块中,而不是__main__中。

事实证明,exec()可以做到这一点。你传入的不是模块,而是字典:

d = my.module.__dict__
exec("some_module_var = 42", d, d)
exec("print(some_module_var)", d, d)

事实上,这大致是 Python 的解释器所做的(从 3.6 开始(,在pythonrun.c中(参见run_mod()PyRun_InteractiveOneObjectEx()(,内置__main__作为模块名称。

相关内容

最新更新