0

I'm writing a script and running it with the -i argument in order to keep the repl open after it finishes in order to be able to see info about the objects that I'm using while debugging.

In order to avoid having to quit and re-run the script I figured out that I can modify and save the script and then import [script-name] and then call my main method with [script-name].[main-method] ().

Now I want to write a single-character method (for convenience) that does:

def x():
    import [this script]
    [this script].[main-method]()

but to also be able to change the script's file name and retain the easy-reloading functionality without having to alter the code.

I've tried using importlib (see below) to no avail.

def y():
   import importlib
   this = importlib.import_module("".join(sys.argv[0].split(".py"))) # sys.argv[0] gives [module-name].py and the rest of the code inside the parentheses removes the ".py"
   this.[main-method]()
martineau
  • 119,623
  • 25
  • 170
  • 301

2 Answers2

1

import, in any of it's incarnations, only reloads the script once. You are looking for the reload function:

from importlib import reload
import sys

def main():
    pass

def x():
    reload(sys.modules[__name__])
    main()

This code will reload the module you are currently in (probably __main__) and rerun a method from it. If you want to reload a script from within the interpreter, do the following instead:

>>> from importlib import reload
>>> def x():
...     reload(mymodule)
...     mymodule.main()
...
>>> import mymodule
>>> mymodule.main()
>>> # Do some stuff with mymodule
>>> x()

You may have to replace import mymodule with mymodule = importlib.import_module("".join(sys.argv[0].split(".py"))) if the script is in a weird location.

Sources:

Community
  • 1
  • 1
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
0

I did it!

def x(): # make what I'm doing now at this very moment easier
   main()
   print("It works!")

def y(): # calls x() after loading most recent version
   import importlib
   from imp import reload
   this = importlib.import_module("".join(sys.argv[0].split(".py"))) # sys.argv gives [module-name].py and the rest of the code inside the brackets removes the ".py"
   this = reload(this)
   this.x()
  • `this = importlib.import_module` only needs to be done once. Make `this` a global, then do `this = reload(this)` to reload. Also `this.main()`. – Mad Physicist Jun 22 '16 at 14:40
  • FYI, `imp` is, for whatever reason, deprecated as of 3.4. But many of its methods exist in `importlib`, including `reload`, so on 3.4 and higher, you can just import `importlib` to get both `import_module` and `reload`. – ShadowRanger Jun 22 '16 at 19:54