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

问题描述 投票:0回答:1

我有一个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__中。)

python read-eval-print-loop
1个回答
0
投票

事实证明,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__作为模块名称。

© www.soinside.com 2019 - 2024. All rights reserved.