Conditional import in Python when creating an object inheriting from it

Viewed 851

I create a package connecting to other libraries (livelossplot). It has a lot of optional dependencies (deep learning frameworks), and I don't want to force people to install them.

Right now I use conditional imports, in the spirit of:

try:
    from .keras_plot import PlotLossesKeras
except ImportError:
    # import keras plot only if there is keras
    pass

However, it means that it imports big libraries, even if one does not intend to use them. The question is: how to import libraries only when one creates a particular object?

For Python functions, it is simple:

def function_using_keras():
   import keras
   ...

What is a good practice for classes inheriting from other classes?

It seems that a parent class needs to be imported before defining an object:

from keras.callbacks import Callback
class PlotLossesKeras(Callback):
    ...
1 Answers

The most straighforward and most easily understood solution would be to split your library into submodules.

It has several advantages over trying to do imports on object initialization:

  1. The user knows what to expect. import my_lib.keras is very likely to depend on keras
  2. Import errors happen during import, not during runtime
  3. You avoid a lot of potential issues by not relying on tricks to inherit from unimported classes
  4. The enduser can very easily switch between implementations by just changing import my_lib.keras to import my_lib.tensorflow

Such a solution could look like

# mylib/__init__.py
class SomethingGeneric():
    pass

def something_else():
    pass

and then

# mylib/keras.py
import keras

class PlotLosses():
    pass

and

# mylib/tensorflow.py
import tensorflow

class PlotLosses():
    pass
Related