Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import all classes (or functions) in all files in folder, as if they were all in the __init__ file

Tags:

I have a folder with multiple files containing a lot of different classes. These could all be in one big file but for the sake of making it a bit easier to read I've split it up in multiple files depending on what the classes belongs to.

I'd like to import all classes from all files in the folder into the __init__ file so that I can import anything from the folder without knowing in what file it belongs to.

Example:

/kitchen  + __init__.py  + fridge.py  + stove.py  + cupboard.py 

Now I have to do

from kitchen.fridge import milk 

When I'd like to do

from kitchen import milk 

The equivalent of this I can get through in __init__.py do:

from kitchen.fridge import * from kitchen.stove import * from kitchen.cupboard import * 

And then I can do

from kitchen import milk 

But I'd like it to take all files in the folder without having to specify it explicitly (so that files can be dumped there and then used).

Is there any way of doing this?

like image 201
olofom Avatar asked May 28 '13 09:05

olofom


People also ask

What is __ import __ in Python?

__import__() Parameters name - the name of the module you want to import. globals and locals - determines how to interpret name. fromlist - objects or submodules that should be imported by name. level - specifies whether to use absolute or relative imports.

What is __ all __ in Python?

Python __all__ is a list of public objects of that module, as interpreted by import *. The __all__ overrides the default of hiding everything that begins with an underscore.

What goes into __ init __ py?

The __init__.py file makes Python treat directories containing it as modules. Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.

How do you import all functions in Python?

We can use import * if we want to import everything from a file in our code. We have a file named functions.py that contains two functions square() and cube() . We can write from functions import * to import both functions in our code. We can then use both square() and cube() functions in our code.


2 Answers

import os, sys  dir_path = os.path.dirname(os.path.abspath(__file__)) files_in_dir = [f[:-3] for f in os.listdir(dir_path)                 if f.endswith('.py') and f != '__init__.py'] for f in files_in_dir:     mod = __import__('.'.join([__name__, f]), fromlist=[f])     to_import = [getattr(mod, x) for x in dir(mod)]                # if isinstance(getattr(mod, x), type)]  # if you need classes only      for i in to_import:         try:             setattr(sys.modules[__name__], i.__name__, i)         except AttributeError:             pass 
like image 79
Daniil Mashkin Avatar answered Nov 20 '22 16:11

Daniil Mashkin


This is a very bad idea. If you want to add a mechanism for files to be "dumped there and used", you probably want to come up with a plugin scheme, and explicitly search the plugin directory(ies).

The way you normally do this is to iterate one or more plugin directories with os.listdir or os.walk, then, for each Python file, use importlib (or lower-level equivalents from imp, in Python 2.x) to import it by path.

However, if you really insist on faking things this way inside a package, you can do basically the same tricks within the __init__.py file, using os.path.dirname(__file__) as the plugin directory.

And, if you really insist on doing the equivalent of from foo import * instead of import foo by path, that's just as easy—or, alternatively, you can use execfile.

If you don't know how to do these simple things, or how to look them up in the docs… then you definitely shouldn't be attempting this. So, I won't provide sample code in this case.

like image 39
abarnert Avatar answered Nov 20 '22 16:11

abarnert