adrin
adrin

Reputation: 4896

how to elegantly parse argumens in python before expensive imports?

I have a script, which parses a few arguments, and has some expensive imports, but those imports are only needed if the user gives valid input arguments, otherwise the program exits. Also, when the user says python script.py --help, there is no need for those expensive imports to be executed at all.

I can think of such a script:

import argparse

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--argument', type=str)
    args = parser.parse_args()
    return args

if __name__ == "__main__":
    args = parse_args()

import gensim # expensive import
import blahblahblah

def the_rest_of_the_code(args):
    pass

if __name__ == "__main__":
    the_rest_of_the_code(args)

This does the job, but it doesn't look elegant to me. Any better suggestions for the task?

EDIT: the import is really expensive:

$ time python -c "import gensim"
Using TensorFlow backend.

real    0m12.257s
user    0m10.756s
sys 0m0.348s

Upvotes: 8

Views: 610

Answers (2)

Elazar
Elazar

Reputation: 21655

Not sure it's better than what you already have, but you can load it lazily:

def load_gensim():
    global gensim
    import gensim

If you only want to make sure the arguments make sense, you can have a wrapper main module that checks the arguments and then loads another module and call it.

main.py:

args = check_args()
if args is not None:
    import mymodule
    mymodule.main(args)

mymodule.py:

import gensim
def main(args):
    # do work

Upvotes: 3

pills
pills

Reputation: 766

You can import conditionally, or in a try block, or just about anywhere in code.

So you could do something like this:

import cheaplib

if __name__ == "__main__":
    args = parse_args()
    if expensive_arg in args:
        import expensivelib
    do_stuff(args)

Or even more clearly, only import the lib in the function that will use it.

def expensive_function():
    import expensivelib
    ...

Upvotes: 8

Related Questions