1

I am porting some matlab code to python. I need to work with packages and modules in this case. The relevant package directory structure looks like this:

toppackage
    __init__.py
    subpackage
        __init__.py
        module.py
        ...

In the script I use the package, I can work like this:

from toppackage.subpackage.module import SomeClass
s = SomeClass()

But I would prefer working like this:

import toppackage %somewhere at the beginning of file
s = toppackage.subpackage.module.SomeClass()

I see this is done in numpy. But I could not find it in documentation. How can I do that?

Thanks in advance.

ozi
  • 1,651
  • 2
  • 17
  • 17

2 Answers2

2

You need to import contained packages in the __init__.py files.

You can import the packages inside the toppackage/__init__.py for example:

import toppackage.subpackage.module

or you can import just each directly contained package, so in toppackage/__init__.py:

from . import subpackage

and in toppackage/subpackage/__init__.py:

from . import module

Just importing the top-level package does not automatically make the contained packages available. You need to explicitly import the full path once, somewhere, before that works.

The numpy package imports the nested packages in the top-level __init__.py.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yes, this works. However this package is in fast development stage, and I expect frequent subpackage changes for modules. It may be cumbersome to remember editing `subpackage/__init__.py` each time. I tried `from . import *` but it does not work. As a possible workaround, can we do this: We can easily find the modules in a subpackage programmaticaly. Assuming variable `module_name` has the name of a module, can we import it? – ozi May 08 '13 at 15:44
  • @ozi: You only need to import modules that are not automatically imported indirectly already. Say `module` imports `from . import utils`, then `utils` is now imported and reachable already. This is not as big a problem as you think it is. – Martijn Pieters May 08 '13 at 15:49
  • Probably it is not a big problem. Still, I found ways to load the modules dynamically after you get their path programmatically: http://stackoverflow.com/questions/301134/dynamic-module-import-in-python – ozi May 08 '13 at 16:09
  • Sure there are, but in my opinion that'd be overkill here. – Martijn Pieters May 08 '13 at 16:10
1

How this stuff works depends critically on what is in __init__.py. Whatever gets imported in that script becomes part of the package namespace.

For example, if your toppackage/__init__.py is empty, to gain access to subpackage, you'd need to do:

import toppackage
try:
    p = toppackage.subpackage
except AttributeError:
    print "you would see this"

import toppackage.subpackage
p = toppackage.subpackage #no error now

however, if toppackage/__init__.py included the line:

#toppackage/__init__.py
import subpackage

Then the above script would raise no Exceptions.

As noted in the comments, you can also use relative imports since you are in a package:

from . import subpackage

This avoids "namespace" conflicts -- e.g. if you have a subpackage named os it will get your subpackage rather than the python-level package.

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 1
    Better not use relative imports; `from . import subpackage` would be preferable. – Martijn Pieters May 08 '13 at 15:08
  • @MartijnPieters -- But that breaks compatibility with python2.4 ;-) – mgilson May 08 '13 at 15:09
  • Do we care about 2.4 that much anymore? 2.6 and up, is what I normally assume. :-) – Martijn Pieters May 08 '13 at 15:10
  • @MartijnPieters -- I was mostly just kidding around. I added that. If memory serves correctly, I believe I've even seen `import toppackage.subpackage as subpackage`. That's actually the form I use inside the submodules themselves, but I'm not sure that I've used it in an `__init__.py` before. – mgilson May 08 '13 at 15:12
  • @MartijnPieters -- In any event, from the standpoint of explaining *how* to manipulate a package's namespace, I like the first form as then you don't need to explain the magic of relative imports. Although, in this case, I would say that the "explicit" relative import is probably best as you pointed out. – mgilson May 08 '13 at 15:14