1

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?

3
  • 1
    This is called "dynamic import" and there are a whole lot of questions already answered: google.com/… Commented Jan 18, 2024 at 21:07
  • An import shouldn't do any I/O; it should only provide a function that can, if necessary, be called to do I/O. Commented Jan 18, 2024 at 21:09
  • Maybe a decorator would be more appropriate? Commented Jan 18, 2024 at 21:46

2 Answers 2

2

quick fix to avoid importing again and again

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

    def bar(self, metadata):     # Online functionality
        if not self.query_call:
            from my_utils import perform_query
            self.query_call = perform_query
        self.query_call(metadata)

    def spam(self):     # Offline functionality
        pass
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.