Skip to content

Commit b9514b3

Browse files
authored
ENH make lazy import of the keras module when importing imblearn (#719)
1 parent 1b8cd47 commit b9514b3

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

doc/whats_new/v0.7.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ Enhancements
3737
:class:`imblearn.ensemble.RUSBoostClassifier`, accept `sampling_strategy`
3838
with the same key than in `y` without the need of encoding `y` in advance.
3939
:pr:`718` by :user:`Guillaume Lemaitre <glemaitre>`.
40+
41+
- Lazy import `keras` module when importing `imblearn.
42+
:pr:`719` by :user:`Guillaume Lemaitre <glemaitre>`.
43+

imblearn/__init__.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
pipeline
3232
Module which allowing to create pipeline with scikit-learn estimators.
3333
"""
34+
import importlib
35+
import types
36+
3437
from . import combine
3538
from . import ensemble
3639
from . import exceptions
37-
from . import keras
3840
from . import metrics
3941
from . import over_sampling
4042
from . import tensorflow
@@ -46,6 +48,50 @@
4648
from ._version import __version__
4749
from .utils._show_versions import show_versions
4850

51+
52+
# # FIXME: When we get Python 3.7 as minimal version, we will need to switch to
53+
# # the following solution:
54+
# # https://snarky.ca/lazy-importing-in-python-3-7/
55+
class LazyLoader(types.ModuleType):
56+
"""Lazily import a module, mainly to avoid pulling in large dependencies.
57+
58+
Adapted from TensorFlow:
59+
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/
60+
python/util/lazy_loader.py
61+
"""
62+
def __init__(self, local_name, parent_module_globals, name, warning=None):
63+
self._local_name = local_name
64+
self._parent_module_globals = parent_module_globals
65+
self._warning = warning
66+
67+
super(LazyLoader, self).__init__(name)
68+
69+
def _load(self):
70+
"""Load the module and insert it into the parent's globals."""
71+
# Import the target module and insert it into the parent's namespace
72+
module = importlib.import_module(self.__name__)
73+
self._parent_module_globals[self._local_name] = module
74+
75+
# Update this object's dict so that if someone keeps a reference to the
76+
# LazyLoader, lookups are efficient (__getattr__ is only called on
77+
# lookups that fail).
78+
self.__dict__.update(module.__dict__)
79+
80+
return module
81+
82+
def __getattr__(self, item):
83+
module = self._load()
84+
return getattr(module, item)
85+
86+
def __dir__(self):
87+
module = self._load()
88+
return dir(module)
89+
90+
91+
# delay the import of keras since we are going to import either tensorflow
92+
# or keras
93+
keras = LazyLoader("keras", globals(), "imblearn.keras")
94+
4995
__all__ = [
5096
"combine",
5197
"ensemble",

0 commit comments

Comments
 (0)