我有一个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__
作为模块名称。