6

Suppose I have a python module called mymodule. At the top of my Code, I have this:

import mymodule
reload(mymodule)

where my directory structure is

/dir/mymodule.py

However, I would like to split mymodule.py into several files, while still being defined as a single module (i.e. I don't want to have to import each file separately - I want to be able to use my import/reload as before).

The only way I know how to do this is the following

/dir/mymodule/
             file1.py
             file2.py
             __init__.py

where __init__.py contains

from file1 import *
from file2 import *

This mostly works, but my call to reload(mymodule) no longer does anything, because it doesn't reload anything called via * imports.

Any suggestions?

rottweiler
  • 229
  • 1
  • 7
  • 1
    I'd like to know the answer to this too. What is the reason for this desired pattern? – BlackVegetable Apr 18 '13 at 22:26
  • 1
    Why do you need to import module and then reload it at once? – Ixanezis Apr 18 '13 at 22:29
  • Just out of curiosity, why is your code structured like this? – Blender Apr 18 '13 at 22:30
  • I have a lot of common functions that I import under the same module, and the single file module started getting long, so I decided to break it into several files. My module is already nested, in another module, and I didn't want to keep nesting. – rottweiler Apr 18 '13 at 22:37
  • Your missing the `__all__` statement in your __init__.py. `__all__` = ['file1','file2'] testing now before I put this as an answer – David Apr 18 '13 at 22:37
  • Ixanezis - I import the module at the beginning of my code and then reload it immediately in case I've made changes to functions in my module. I do this all inside of iPython, and without reloading it I have to close iPython and open it again. – rottweiler Apr 18 '13 at 22:38
  • @David I tried that, but my understanding was that the `__all__` statement only helps if you're doing a * import – rottweiler Apr 18 '13 at 22:39
  • What version of Python are you using? with/without `__all__` reload didn't lose any properties after reload in Pyth 2.7.4 – David Apr 18 '13 at 22:42
  • @rottweiler Also, not relevant to question but I'd highly recommend not using import * inside an `__init__.py` file as it makes it very tedious for someone else to understand where things came from and what they're doing. Ideally code is write once, read many times. – David Apr 18 '13 at 22:43
  • I'm using 2.7.2. I tried using `__all__ = ['file1', 'file2']` and now to import things from `file1.py` I need to call `import mymodule.file1`, instead of just `import mymodule` – rottweiler Apr 18 '13 at 22:51

2 Answers2

1

I'm not sure exactly why you're doing this, but will assume you have you reasons. I think this works:

__init__.py:

import file1
reload(file1)
from file1 import *

Obviously you can import file2 as well

GeorgeWilson
  • 562
  • 6
  • 17
  • Please edit your post to add backticks around `__init__.py`... right now it is showing in bold. I can't edit it because it wants me to change 6 characters, but the backticks is only two characters. – SethMMorton Apr 18 '13 at 23:14
  • David nicely did it for me. – GeorgeWilson Apr 18 '13 at 23:27
  • Can you explain why you don't endorse it? Seems like a pretty good workaround. – rottweiler Apr 18 '13 at 23:39
  • I just mean that the whole situation seems a little strange (reloading your module and using star imports etc), so I'm suggesting this as exactly what you say it is: a workaround. I've edited my answer though. – GeorgeWilson Apr 19 '13 at 00:22
1

For a quick workaround I could suggest

import sys

def myreload(base_module_name):
    for module_name, module in sys.modules.items():
        if module_name.startswith(base_module_name):
            reload(module)

myreload('mymodule')

This would call reload(mymodule.file1), reload(mymodule.file2) etc.

However, it is not recursive and as you are using ipython, I believe your quiestion is well answered here.

Community
  • 1
  • 1
Ixanezis
  • 1,631
  • 13
  • 20