4

I have 2 self-defined packages pac1 and pac2. I used to import all the modules one by one and reload them one by one after change, like so:

from pac1 import mod1
from pac1 import mod2
from pac1 import mod3
from pac2 import mod4
from pac2 import mod5

reload(mod1)
reload(mod2)
reload(mod3)
reload(mod4)
reload(mod5)

Now, I learn that I can batch import the modules and improve the codes to:

from pac1 import *
from pac2 import *

reload(mod1)
reload(mod2)
reload(mod3)
reload(mod4)
reload(mod5)

But is this the best I can do? I mean can I reload all the packages in one go?

UPDATE1: I am constantly modifying these modules. So after importing them at the start of the testing, I may need to frequently reload the modified modules to reflect the changes. This is the incentive for me to reload the modules.

UPDATE2: This process is not necessarily done dynamically. I just want to make my code more concise by fusing all those reload() into one.

  • 2
    Why do you need to reload them right after importing them? – DanielB Oct 15 '13 at 14:54
  • @DanielB Because I constantly modify them. Please see editted. –  Oct 15 '13 at 15:00
  • If the code is just there for reloading during testing, does it really matter if it is concise? You could put it in each of the `pac*` files if you wanted it to be *neater*. – DanielB Oct 15 '13 at 15:18

3 Answers3

1

There's a global list of modules in sys.modules (in fact, it's a dict). If you want to reload every module which is in the global namespace, try this:

import sys,imp
def reloader(globaldict):
    reloadkeys = set(globaldict)&set(sys.modules)
    for key in reloadkeys:
        if imp.is_builtin(key) == 0:
            reload(sys.modules[key])

reloader(locals())

Or, if you want to keep track yourself, just create your own list of modules mymodules, and append each module to it after importing it. Then you can use a loop to reload each one.


Here's a way which avoids reloading builtins without examining globals:

import sys,imp
def reloader(globaldict):
    for key in sys.modules:
        if imp.is_builtin(key) == 0:
           reload(sys.modules[key])

Also, you could capture the state of sys.modules right after starting the interpreter, and exclude those from your reload using similar boolean operations.

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • I think that simply keeping a list of imported modules is the best idea one can get, reloading all modules from sys.modules may be too troublesome - I for instance have about 300 of them, imagine reloading each of them a couple of times... – Pawel Miech Oct 15 '13 at 15:42
  • @Pawelmhm Note that I specifically provide code which *does not* reload every module in sys.modules. – Marcin Oct 15 '13 at 15:45
0

You might try something like this

Alternatively, you could look at how Werkzeug (Flask) does it, which looks like it uses subprocess to call itself, or the main portion of the code anyway.

Community
  • 1
  • 1
Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • Link only answers aren't good answers. If the link ever goes dark then the answer becomes useless. Please include the essential parts of the answer here. – ChrisF Nov 10 '13 at 17:00
  • @ChrisF typically I frown on those too... In this particular case I'm assuming that if Github goes dark we have bigger problems ;) – Wayne Werner Nov 11 '13 at 03:25
  • (I suppose the counter argument to that is that it's perfectly possible for mitsuhiko to delete his branch...) I did try to include the main gist in my answer. – Wayne Werner Nov 11 '13 at 03:26
-1

Assuming you really need to reload them, the way you are doing it is best because it is explicit (and explicit is better than implicit). It makes it clear whats going on (especially since this is not a normal situation)

If you really need to do it dynamically, you can try something like this:

import types

for k, v in globals().items():
    if not (k.startswith('__') and k.endswith('__')):
        if isinstance(v, types.ModuleType):
            reload(v)
DanielB
  • 2,798
  • 1
  • 19
  • 29