54

Goal

I want to be able to import (on the __init__.py) all functions from every single file inside my package.

Usage

For example in this folder structure.

manage.py
- scripts/
   -- __init__.py
   -- tests.py
   -- deploy.py

I am currently doing the following:

manage.py:

from scripts import *

script/init.py:

from .tests import *
from .deploy import *

But, every time I add another file to the package I have to add an import line on script/__init__.py, which is kind of annoying.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
CESCO
  • 7,305
  • 8
  • 51
  • 83
  • 14
    Believe me, you really **dont** want to "automate" this. The way you're doing it is already bad enough (in that you have to read both files to find out where a name comes from). Been here, done that... and finally came back to the sane solution: **explicit** imports everywhere. – bruno desthuilliers Jan 18 '16 at 12:46
  • 11
    Please, _please_ don't do this. `from foo import *` is bad enough; if you find a way to import every single thing across multiple files you're not just going to end up shooting yourself in the foot, you're going to blow your whole leg off. https://stackoverflow.com/questions/2386714/why-is-import-bad Remember, [PEP-20](https://www.python.org/dev/peps/pep-0020/) tells us that "explicit is better than implicit". – ChrisGPT was on strike Jan 18 '16 at 12:47
  • 2
    @Chris thanks! explicit importing everything everywhere now – CESCO Jan 18 '16 at 12:54
  • 22
    I cannot understand why people downvote such questions. There are no bad/stupid questions. And this one is well formed/explained. Instead of downvoting, take the time to comment/answer. – Pynchia Jan 18 '16 at 12:54
  • 4
    The question just received the good question badge. Guess they where all wrong back then. – CESCO May 08 '17 at 12:25

2 Answers2

29

You can do it, manually, but you shouldn't.

Why you really do not want to do this:

You'll end up with a namespace where understanding what is what and from where it came from will be extremely hard, with difficulty increasing as the size of the overall project does. Appart from being completely unintuitive for Python, think of anybody else that might view your code or even worse, think about yourself re-reading it after 1 month and not remembering what's going on. You don't need that in your life.

In addition to that, any functions you expose to the importer that might overlap with other functions in other modules are going to get shaddowed by the most recent one imported. As an example, think of two scripts that contain the same function foo() and watch what happens.

>>> from scrpt1 import *
>>> foo()
Script 1
>>> from scrpt2 import *
>>> foo()
Script 2

Don't need that in your life either. Especially when it is so easy to bypass by being explicit.


Here are some related lines from the text contained in import this:

Explicit is better than implicit.

Be explicit about the place where your functions are defined in. Don't "spaghetti" your code. You'll want to hit yourself in the future if you opt in for a mesh of all stuff in one place.

Special cases aren't special enough to break the rules.

Really self explanatory.

Namespaces are one honking great idea -- let's do more of those!

"more of those!", not less; don't miss out on how wonderful namespaces are. Python is based on them; segregating your code in different namespaces is the foundation of organizing code.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • 13
    Rather than just supplying your 2-cents on the question, I'd recommend actually answering it, and then supplying your 2-cents if you must. – Mano Sep 09 '20 at 14:09
15
  1. importlib allows you to import any Python module from a string name. You can automate it with going through the list of files in the path.

  2. It's more pythonic to use __all__. Check here for more details.

Dhia
  • 10,119
  • 11
  • 58
  • 69
  • I wouldn't go so far as to say it's the _only_ way. It's the only _easy_ way, but with python's introspection it's possible to dynamically load every module in a directory. – Bryan Oakley Jan 18 '16 at 14:31
  • 2
    [importlib](https://docs.python.org/3.5/library/importlib.html#module-importlib) has methods for importing modules by file name. `__init__.py` can simply iterate over all of the filenames in a directorn and import each file that it finds. – Bryan Oakley Jan 18 '16 at 14:46
  • @CESCO: while using importlib makes this possible, in general this is a very bad thing to do. It will make your code harder to understand and maintain over time. This technique is best for very specific cases, such as supporting the ability to add plugins to an application. – Bryan Oakley Jan 18 '16 at 16:49
  • @BryanOakley I got that! Thanks. I am explicitly importing everything everywhere now. Now just fiddling with this for educational sake. I got this https://gist.github.com/ddad728b227f75d13a36 to work, except that is not importing the way I wanted too. – CESCO Jan 18 '16 at 16:58
  • I could not make it work how I want yet. Although it helped me a lot, this is not the answer yet. @DhiaTN – CESCO Jan 19 '16 at 15:01