How to import members of all modules within a package?
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.
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 except for those whose names 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 the.foo_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
:
from package import *
print(example('derp'))
__init__.py
:
def _import_all_modules():
""" Dynamically imports all modules in this package. """
import traceback
import os
global __all__
__all__ = []
globals_, locals_ = globals(), locals()
# Dynamically import all the package modules in this file's directory.
for filename in os.listdir(__name__):
# Process all python files in directory that don't start
# with underscore (which also prevents this module from
# importing itself).
if filename[0] != '_' and filename.split('.')[-1] in ('py', 'pyw'):
modulename = filename.split('.')[0] # Filename sans extension.
package_module = '.'.join([__name__, modulename])
try:
module = __import__(package_module, globals_, locals_, [modulename])
except:
traceback.print_exc()
raise
for name in module.__dict__:
if not name.startswith('_'):
globals_[name] = module.__dict__[name]
__all__.append(name)
_import_all_modules()
foo_module.py
:
def foo(bar):
return bar
example_module.py
:
from .foo_module import foo # added
def example(arg):
return foo(arg)
Import all modules in a package programatically
you have to append the package name ate to the beginning of the module string for this to work , otherwise it gave a no module named <filename> ImportError
.
import os
import importlib
for module in os.listdir(os.path.dirname(__file__)):
if module == '__init__.py' or module[-3:] != '.py':
continue
__import__(__name__+'.'+module[:-3], locals(), globals())
del module
you can use importlib
import os
import importlib
for module in os.listdir(os.path.dirname(__file__)):
if module == '__init__.py' or module[-3:] != '.py':
continue
importlib.import_module("."+module[:-3], __name__ )
del module
the best way is to list all python (.py) files in the current folder and put them as all variable in init.py
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
Import all modules from a package
Python 3.x has changed import resolution. You must now specify a full relative import if you want to perform a relative import.
from .add import add
How to load all modules in a folder?
List all python (.py
) files in the current folder and put them as __all__
variable in __init__.py
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
Import all modules from the package
This is another answer that might be closer to what you want.
In __init__.py
you can add this to import all python files in the package.
Note that it doesn't do packages.. not sure how. And I'm using windows
from os import listdir
from os.path import abspath, dirname, isfile, join
# get location of __init__.py
init_path = abspath(__file__)
# get folder name of __init__.py
init_dir = dirname(init_path)
# get all python files
py_files = [file_name.replace(".py", "") for file_name in listdir(init_dir) \
if isfile(join(init_dir, file_name)) and ".py" in file_name and not ".pyc" in file_name]
# remove this __init__ file from the list
py_files.remove("__init__")
__all__ = py_files
How to package a python module that imports another module within that package
Please try to import it as below ...
from foo.helper_class import HelperClass
python: list modules within the package
ok, this was actually pretty straightforward:
import pkg
sub_modules = (
pkg.__dict__.get(a) for a in dir(pkg)
if isinstance(
pkg.__dict__.get(a), types.ModuleType
)
)
for m in sub_modules:
for c in (
m.__dict__.get(a) for a in dir(m)
if isinstance(m.__dict__.get(a), type(Base))
):
""" c is what I needed """
Related Topics
Websocket VS Rest API for Real Time Data
Number of Days Between 2 Dates, Excluding Weekends
How to Get Integer Values from a String in Python
Matplotlib Log Scale Tick Label Number Formatting
Reducing Size of Pyinstaller Exe
Split a List into Parts Based on a Set of Indexes in Python
Find Longest Repetitive Sequence in a String
Django Smtpauthenticationerror
List of Dicts To/From Dict of Lists
How to Config Nltk Data Directory from Code
Check What Files Are Open in Python
Django Aggregation: Summation of Multiplication of Two Fields
Multiprocessing.Dummy in Python Is Not Utilising 100% Cpu
How to Decorate an Instance Method with a Decorator Class
Removing Unicode \U2026 Like Characters in a String in Python2.7