views:

159

answers:

2

As I just found out import package does not make the package's modules available through package.module. The same obviously holds true for from package import subpackage as well as from package import *

What's the purpose of importing a package at all then if I can't access its submodules but only the objects defined in __init__.py?

It makes sense to me that from package import * would bloat the namespace, which, however, doesn't apply in case of the other two ways! I also understand that loading all submodules might take a long time. But I don't know what these unwanted side-effects, "that should only happen when the sub-module is explicitly imported", are which the author of the previous link mentions. To me it looks like doing an import package[.subpackage] (or from package import subpackage) makes absolutely no sense if I don't exactly want to access objects provided in __init__.py.

Are those unwanted side effects really that serious that the language actually has to protect the programmer from causing them? Actually, I thought that Python was a little bit more about "If the programmer wants to do it, let him do it." In my case, I really do want to import all submodules with the single statement from package import subpackage, because I need all of them! Telling Python in the __init__.py file which submodules I'm exactly talking about (all of them!) is quite cumbersome from my point of view.

Please enlighten me. :)

+2  A: 

It's up to the package if it automatically imports submodules in its __init__.py or not. For example os automatically imports os.path, so this works:

import os
print os.path.abspath('somefile')

So the creator of the package can decide what is best. If automatically loading all submodules would take a rather long time and would rarely be needed, it probably shouldn't be done. If all the submodules are always required they probably should be imported automatically.

If you think a package imports not enough you could work around it by writing your own wrapper module that does all the imports, and then use that with from wrappermodule import *.

sth
Adding to this, in summary import package allows more choices to the package designer. At minimum it provides name-spacing but if warranted or desired import package can add functions, classes, and sub-packages to itself. The extra functionality is there if you need it but not forced or required.
David
The only fact that's bugging me, now, is that there's practically no way I could automatically import **all** submodules. (Besides the solution by Roger Pate below that I'd rather consider a hack.) That somehow limits the "freedom" both of you mention. Yet, I see your point that the package designer should make that decision.
codethief
+1  A: 

As said, the solution is to import each submodule. You can use a hack to avoid listing them:

__init__.py

import os

def import_sub():
  for fn in os.listdir(os.path.dirname(__file__)):
    if fn.endswith(".py") and fn != "__init__.py":
      __import__(".".join([__name__, os.path.basename(fn)[:-3]]), level=0)
import_sub()
del import_sub  # if desired

This will easily break under some circumstances. However, it will handle the common case and could be temporarily suitable.

Roger Pate
Although it's rather inelegant, I might use it. Thanks!
codethief
Why oh why.....
Mike Graham