简体   繁体   English

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

[英]Execute REPL code in the context of a Python module and not __main__?

I have a Python instance, with a REPL open and several modules imported. 我有一个Python实例,上面有一个REPL打开,并导入了几个模块。 Can I run code as if it was part of one of these modules? 我是否可以将代码当作这些模块之一的一部分来运行?

Example: my.module includes code like 示例:my.module包含如下代码

  some_module_var = 123

  def my_function():
    return 7

I want to be able to type 我希望能够输入

new_module_var = my_function(some_module_var)

in some form into the REPL and have it executed as if it was part of the module, instead of 以某种形式放入REPL中,并像执行模块一样执行它,而不是

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

Is there a nice solution for this? 有一个好的解决方案吗?

The one thing I already tried is 我已经尝试过的一件事是

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

with the module as the global namespace, but, apparently, namespaces can't be modules. 将模块作为全局命名空间,但是显然,命名空间不能是模块。

Also, as a workaround, we could just copy every symbol from the module to the global namespace, run the eval, then copy back changes... it doesn't feel as elegant though as eg Common Lisp's "just switch the REPL package" solution though. 另外,作为一种解决方法,我们可以将模块中的每个符号复制到全局名称空间,运行eval,然后复制回更改……这并不像Common Lisp的“只是切换REPL包”那样优雅。解决方案。

Or is there a custom REPL that can do this? 还是有可以执行此操作的自定义REPL?

(... my goal is to be able to send entire functions to a running Python instance & have them show up in the right module, not in __main__ .) (...我的目标是能够将整个函数发送到正在运行的Python实例,并使它们显示在正确的模块中,而不是在__main__ 。)

As it turns out, exec() can do this. 事实证明, exec()可以做到这一点。 You pass in not the module but it's dictionary: 您传入的不是模块,而是字典:

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

In fact, this is roughly what Python's interpreter does (as of 3.6), in pythonrun.c (see run_mod() and PyRun_InteractiveOneObjectEx() ), with __main__ built in as the module name. 实际上,这大致就是Python的解释器(从3.6版本开始)在pythonrun.c (请参阅run_mod()PyRun_InteractiveOneObjectEx() ),其中内置__main__作为模块名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM