Search code examples
pythonpython-3.xpython-importpython-class

On demand Python imports


I have the following situation: A module that contains a class Foo with some additional convenience functions for assembling Foo objects. A Foo object contains methods for interacting with data in an online and offline fashion. Depending on the user, they may not want to utilize the online functionality and I want to avoid asking for their credentials if they are not trying to do anything online. I would like to keep the credential_obj as an import if possible since a Python instance doesn't need to reload imports after they have been imported once.

# my_utils.py

def perform_query(metadata):
    from auth import credential_obj  # This import asks for a password
    # perform the query and save to file

# my_foo.py

class Foo:
    def __init__(self, x):
        # Do something with x to find search for local files
        # and populate metadata

    def bar(self, metadata):     # Online functionality
        from my_utils import perform_query
        perform_query(metadata)

    def spam(self):     # Offline functionality
        pass
        
def find_foos(xs):
    list_of_foos = [Foo(x) for x in xs]
    return list_of_foos
# my_script.py

from my_foo import find_foos  # this causes "credential_obj" to be imported and asks for the password

foos = find_foos()

for foo in foos:
    foo.spam()

I was hoping that by including the import statements within the class method, the import would only run when "bar" was executed - but that doesn't seem to be the case. The "my_script" only utilizes offline functionality but still is asked for credentials. Is there anyway to prevent the import from occuring when find_foos is imported?


Solution

  • Thanks to Ben Voigt, I quickly found a solution:

    # my_utils.py
    
    from importlib import import_module
    
    def perform_query(metadata):
        auth = import_module('auth')
        # perform the query and save to file using auth.credential_obj