简体   繁体   中英

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. Can I run code as if it was part of one of these modules?

Example: my.module includes code like

  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

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.

Or is there a custom REPL that can do this?

(... 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__ .)

As it turns out, exec() can do this. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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