Hide external modules when importing a module (e.g. regarding code-completion)
Question:
I have several modules in one package (a kind of a toolkit), which I use in my projects. The structure looks like this:
the_toolkit:
__init__.py
basic_io.py
simple_math.py
matrix_kit.py
...
Now when I use IPython
or the code completion in VIM
after importing a module from the package with
from the_toolkit import matrix_kit
I get a bunch of modules/functions which matrix_kit.py
imports (array
, math
, log
, loggin
, format_exc
, etc.), along with the actual functions which matrix_kit
defines.
How can I filter out everything else, since I’m not interested in math
or array
in a code completion of the matrix_kit
module?
The __init__.py
is empty as suggested by many pythonistas, or is it the way to do it?
Answers:
you may get some mileage out of __all__
I had the same problem, and solved it by adding a leading underscore to all my imports. It doesn’t look brilliant, but it achieves what you’re after.
from __future__ import division as _division
import numpy as _np
import pandas as _pd
Only the stuff that starts without an underscore is imported when you import the module using from .. import *. or when you use tab-completion in IPython or spyder.
I’ve come to like and use this approach. Starting with your project structure, we will hide all the content of matrix_kit
that you don’t want to show.
the_toolkit:
__init__.py
basic_io.py
simple_math.py
matrix_kit.py
...
Move matrix_kit.py
into a package with the same name, and place one underscore in the beginning of the module’s name:
the_toolkit:
__init__.py
basic_io.py
simple_math.py
matrix_kit:
__init__.py
_matrix_kit.py
...
Now in _matrix_kit.py
add a global variable __all__ = [...]
listing the names of all functions/classes/variables you want to be visible. Then, add the following line to matrix_kit/__init__.py
:
from ._matrix_kit import *
It will only import the stuff listed in the __all__
attribute of the module. Then, while importing matrix_kit
like you’ve done before, you will actually import the __init__.py
and its content.
An alternative solution I came up with is to implement a short API class in the __init__
file which can make use of the __all__
variable (which may already be defined for import *
purposes). Something like this in __init__.py
:
import matrix_kit
class _matrix_kit_API:
def __init__(self):
for func in matrix_kit.__all__:
setattr(self, func, eval(f"matrix_kit.{func}"))
matrix_kit = _matrix_kit_API()
I have several modules in one package (a kind of a toolkit), which I use in my projects. The structure looks like this:
the_toolkit:
__init__.py
basic_io.py
simple_math.py
matrix_kit.py
...
Now when I use IPython
or the code completion in VIM
after importing a module from the package with
from the_toolkit import matrix_kit
I get a bunch of modules/functions which matrix_kit.py
imports (array
, math
, log
, loggin
, format_exc
, etc.), along with the actual functions which matrix_kit
defines.
How can I filter out everything else, since I’m not interested in math
or array
in a code completion of the matrix_kit
module?
The __init__.py
is empty as suggested by many pythonistas, or is it the way to do it?
you may get some mileage out of __all__
I had the same problem, and solved it by adding a leading underscore to all my imports. It doesn’t look brilliant, but it achieves what you’re after.
from __future__ import division as _division
import numpy as _np
import pandas as _pd
Only the stuff that starts without an underscore is imported when you import the module using from .. import *. or when you use tab-completion in IPython or spyder.
I’ve come to like and use this approach. Starting with your project structure, we will hide all the content of matrix_kit
that you don’t want to show.
the_toolkit:
__init__.py
basic_io.py
simple_math.py
matrix_kit.py
...
Move matrix_kit.py
into a package with the same name, and place one underscore in the beginning of the module’s name:
the_toolkit:
__init__.py
basic_io.py
simple_math.py
matrix_kit:
__init__.py
_matrix_kit.py
...
Now in _matrix_kit.py
add a global variable __all__ = [...]
listing the names of all functions/classes/variables you want to be visible. Then, add the following line to matrix_kit/__init__.py
:
from ._matrix_kit import *
It will only import the stuff listed in the __all__
attribute of the module. Then, while importing matrix_kit
like you’ve done before, you will actually import the __init__.py
and its content.
An alternative solution I came up with is to implement a short API class in the __init__
file which can make use of the __all__
variable (which may already be defined for import *
purposes). Something like this in __init__.py
:
import matrix_kit
class _matrix_kit_API:
def __init__(self):
for func in matrix_kit.__all__:
setattr(self, func, eval(f"matrix_kit.{func}"))
matrix_kit = _matrix_kit_API()