I’m using the following code to populate __all__ in my module’s __init__.py and I was wandering if there was a more efficient way. Any ideas?
import fnmatch
import os
__all__ = []
for root, dirnames, filenames in os.walk(os.path.dirname(__file__)):
root = root[os.path.dirname(__file__).__len__():]
for filename in fnmatch.filter(filenames, "*.py"):
__all__.append(os.path.join(root, filename[:-3]))
You probably shouldn’t be doing this: The default behaviour of
importis quite flexible. If you don’t want a module (or any other variable) to be automatically exported, give it a name that starts with_and python won’t export it. That’s the standard python way, and reinventing the wheel is considered unpythonic. Also, don’t forget that other things besides modules may need exporting; once you set__all__, you’ll need to find and export them as well.Still, you ask how to best generate a list of your exportable modules. Since you can’t export what’s not present, I’d just check what modules of your own are known to your main module:
sys.modulesincludes the names of every module that python has loaded, including many that have not been exported to your main module– so we check if they’re inlocals().This is faster than scanning your filesystem, and more robust than assuming that every
.pyfile in your directory tree will somehow end up as a top-level submodule. Naturally you should run this code near the end of your__init__.py, when everything has been loaded.