I am developing a package that has a file structure similar to the following:
test.py
package/
__init__.py
foo_module.py
example_module.py
If I call import package
in test.py, I want the package module to appear similar to this:
>>> vars(package)
mapping_proxy({foo: <function foo at 0x…}, {example: <function example at 0x…})
In other words, I want the members of all modules in package
to be in package
's namespace, and I do not want the modules themselves to be in the namespace. package
is not a sub-package.
Let's say my files look like this:
foo_module.py:
def foo(bar):
return bar
example_module.py:
def example(arg):
return foo(arg)
test.py:
print(example('derp'))
How do I structure the import statements in test.py, example_module.py, and __init__.py to work from outside the package directory (i.e. test.py) and within the package itself (i.e. foo_module.py and example_module.py)? Everything I try gives Parent module '' not loaded, cannot perform relative import
or ImportError: No module named 'module_name'
.
Also, as a side-note (as per PEP 8): "Relative imports for intra-package imports are highly discouraged. Always use the absolute package path for all imports. Even now that PEP 328 is fully implemented in Python 2.5, its style of explicit relative imports is actively discouraged; absolute imports are more portable and usually more readable."
I am using Python 3.3.
I was able to do that by adapting something I've used in Python 2 to automatically import plug-ins to also work in Python 3.
In a nutshell, here's how it works:
The package's
__init_.py
file imports all the other Python files in the same package directory that don't start with an'_'
(underscore) character.It then adds any names in the imported module's namespace to that of
__init__
module's (which is also the package's namespace). Note I had to make theexample_module
module explicitlyimport foo
from thefoo_module
.One important aspect of doing things this way is realizing that it's dynamic and doesn't require the package module names to be hardcoded into the
__init__.py
file. Of course this requires more code to accomplish, but also makes it very generic and able to work with just about any (single-level) package — since it will automatically import new modules when they're added and no longer attempt to import any removed from the directory.test.py
:__init__.py
:foo_module.py
:example_module.py
:I think you can get the values you need without cluttering up your namespace, by using
from module import name
style imports. I think these imports will work for what you are asking for:Imports for
example_module.py
:Imports for
__init__.py
:Imports for
test.py
:Note that this only works if you're running
test.py
(or something else at the same level of the package hierarchy). Otherwise you'd need to make sure the folder containingpackage
is in the python module search path (either by installing the package somewhere Python will look for it, or by adding the appropriate folder tosys.path
).