I'm writing a data manipulation package based on python pandas. For the part which has a functional style, I would like to make my package hierarchy flatter. Currently functions need to be imported using calls such as:
from package.module.submodule import my_function
The proposed change would make it possible to import
from package import my_function
To achieve this, functions and other objects would be imported into package/__init__.py
so that they are available in the top level name space. This is how pandas does it, for example pandas/__init__.py
makes it possible to import
from pandas import DataFrame
When in fact, the DataFrame class is defined inside pandas.core.frame. You would normally have to import it like this: from pandas.core.frame import DataFrame
, but since it's imported in the top level __init__.py
it's made available at the top level.
Making functions available as top level imports:
would expose a flat hierarchy for users and would make it easier to use the package
but internally (in the package code) we should not import from
package/__init__.py
directly to avoid creating circular references.- Searching for from+pandas+import It seems that pandas always avoids importing from the top level (except test scripts which do use from pandas import DataFrame). I don't know how to enforce this.
- Maybe this tool can be helpful: pylint-forbidden-imports,
- or rather flake8-tidy-imports since we are using black and flake8 as a pre commit hook. flake8-tidy-imports makes it possible to define which imports are forbidden. It seems it applies to the whole package though, and not to a specific location in the package.
Related questions
- Best practices for top level __init__.py imports
- Can someone explain __all__ in Python?
- the accepted answer mentions "I personally write an
__all__
early in my development lifecycle for modules so that others who might use my code know what they should use and not use."
- the accepted answer mentions "I personally write an