Python – 'import' or pass modules as parameters?

Question:

I was wondering if passing module objects to a class or object which requires it rather than using import might not be a bad idea, as it avoids hard dependencies on those modules.

I was wondering if someone more aware of the Python Zen than I might be able to explain why this is a terrible/not terrible idea?

Asked By: Magnus

||

Answers:

What you’re talking about is called dependency injection and is considered a good practice for making your code testable. I don’t think there’s anything about Python that would make it unPythonic or a bad practice.

There are other ways you could do it in Python, for example by importing different modules depending on some kind of flag you pass in:

class Foo(object):
    def __init__(self, testing=False):
        if testing:
            import module_test as module
        else:
            import module
        self.module = module

But passing a reference to the module you wish to use is more flexible, separates concerns better, and is no less Pythonic than passing a reference to a class or instance (or string or integer) you wish to use.

For the ordinary (non-test) use case, you can use a default argument value:

class Foo(object):
    def __init__(self, module=None):
        if not module:
            import module
        self.module = module
Answered By: kindall

If the class in question can use one of several different modules, then it could make sense to pass in the one you want it to use.

In every situation I have encountered so far, however, the modules needed are certain, so using import would be preferred.

Answered By: Ethan Furman

I’m late for the game, but I have just learned a way to do this and wanted to share:

chosen_config='moduleName' #string, relative path. example: 'configurations.local.logistic'. You would take this from input, or the command line, or something like that
import importlib
config=importlib.import_module(chosen_config,package='myPackage')
#...do stuff...
data=pd.read_csv(config.dataFile)
#...more stuff...
save(config.outputFile)

Is equivalent to:

import moduleName as config

But I let the user (aka Future Me or someone I trust) decide which module to import.

Use case (my situation): You want to run a series of experiments with a sequence of different settings that will affect several scripts. You have stored the settings for each experiment in a dedicated config file. You want to run all the tasks without modifying your code.

Answered By: alex
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.