0

I have this simple script named test1.py.

#!/usr/bin/env python

from argparse import ArgumentParser


def cmdlineparse():
    parser = ArgumentParser()
    parser.add_argument("-tid", dest="CHEMBL_TARGET_ID", required=True, type=str)
    parser.add_argument("-molfile", dest="XTEST_MOLFILE", required=False, type=str)

    args=parser.parse_args()
    return args


if __name__ == '__main__':

    args = cmdlineparse()

    print("The given CHEMBL_TARGET_ID is %s" % args.CHEMBL_TARGET_ID)
    print("The given XTEST_MOLFILE is %s" % args.XTEST_MOLFILE)

Normally, I execute it like this ./test1.py -tid CHEMBL8868 -molfile ligands.sdf.

What I want to do is to execute it multiple times from within a second script named test2.py. The simplest solution would be to call it using subprocess.call or something equivalent.

subprocess.call("./test1.py -tid CHEMBL8868 -molfile ligands.sdf".split(), shell=True, executable='/bin/bash')

However, I would like to do it in a more elegant way, namely by importing it as a module and passing values to argparse. Could someone please show me how to do this?

1
  • 2
    parse_args() gets values from list sys.argv but you can use own list parse_args(my_list) Commented May 4, 2019 at 13:26

1 Answer 1

2

You'll need to refactor your script a bit: let cmdlineparse take an list of arguments to parse, and define a function main that does the actual work instead of a bare block guarded by __main__.

#!/usr/bin/env python

from argparse import ArgumentParser


def cmdlineparse(args):
    parser = ArgumentParser()
    parser.add_argument("-tid", dest="CHEMBL_TARGET_ID", required=True, type=str)
    parser.add_argument("-molfile", dest="XTEST_MOLFILE", required=False, type=str)

    args=parser.parse_args(args)
    return args

def main(args=None):
    args = cmdlineparse(args)
    print("The given CHEMBL_TARGET_ID is %s" % args.CHEMBL_TARGET_ID)
    print("The given XTEST_MOLFILE is %s" % args.XTEST_MOLFILE)


if __name__ == '__main__':
    main()

Without an argument, main will parse the current command-line arguments, since a value of None passed (eventually) to parser.parse_args() will cause it to parse sys.argv[1:].

Now you can import test1 and call main explicitly as often as you like:

import test1

test1.main(["-tid", "CHEMBL8868", "-molfile", "ligands.sdf"])
test1.main(["-tid", "CHEMBL8293", "-molfile", "stuff.sdf"])
# etc
Sign up to request clarification or add additional context in comments.

5 Comments

Is it possible to have the print statements within if __name__ == '__main__':?
You can put anything you want there; there's really nothing special about it, aside from the "magic" that sets the value of __name__ in the first place.
I mean that prints were just an example. I have to transfer all the execution code under the main() definition otherwise nothing is executed.
I am not sure what you are asking. The point is that outside the if block, you only have function definitions and (maybe) variable definitions. You can call main (as the entry point) in the if block so that test1 can still be used as a script, but if you import test1 as a regular module, none of the defined functions are called unless you call them explicitly.
OK, I will move all execution code inside main() then.

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.