In Python, can I call the main() of an imported module?

Solution 1:

It's just a function. Import it and call it:

import myModule

myModule.main()

If you need to parse arguments, you have two options:

  • Parse them in main(), but pass in sys.argv as a parameter (all code below in the same module myModule):

    def main(args):
        # parse arguments using optparse or argparse or what have you
    
    if __name__ == '__main__':
        import sys
        main(sys.argv[1:])
    

    Now you can import and call myModule.main(['arg1', 'arg2', 'arg3']) from other another module.

  • Have main() accept parameters that are already parsed (again all code in the myModule module):

    def main(foo, bar, baz='spam'):
        # run with already parsed arguments
    
    if __name__ == '__main__':
        import sys
        # parse sys.argv[1:] using optparse or argparse or what have you
        main(foovalue, barvalue, **dictofoptions)
    

    and import and call myModule.main(foovalue, barvalue, baz='ham') elsewhere and passing in python arguments as needed.

The trick here is to detect when your module is being used as a script; when you run a python file as the main script (python filename.py) no import statement is being used, so python calls that module "__main__". But if that same filename.py code is treated as a module (import filename), then python uses that as the module name instead. In both cases the variable __name__ is set, and testing against that tells you how your code was run.

Solution 2:

Martijen's answer makes sense, but it was missing something crucial that may seem obvious to others but was hard for me to figure out.

In the version where you use argparse, you need to have this line in the main body.

args = parser.parse_args(args)

Normally when you are using argparse just in a script you just write

args = parser.parse_args()

and parse_args find the arguments from the command line. But in this case the main function does not have access to the command line arguments, so you have to tell argparse what the arguments are.

Here is an example

import argparse
import sys

def x(x_center, y_center):
    print "X center:", x_center
    print "Y center:", y_center

def main(args):
    parser = argparse.ArgumentParser(description="Do something.")
    parser.add_argument("-x", "--xcenter", type=float, default= 2, required=False)
    parser.add_argument("-y", "--ycenter", type=float, default= 4, required=False)
    args = parser.parse_args(args)
    x(args.xcenter, args.ycenter)

if __name__ == '__main__':
    main(sys.argv[1:])

Assuming you named this mytest.py To run it you can either do any of these from the command line

python ./mytest.py -x 8
python ./mytest.py -x 8 -y 2
python ./mytest.py 

which returns respectively

X center: 8.0
Y center: 4

or

X center: 8.0
Y center: 2.0

or

X center: 2
Y center: 4

Or if you want to run from another python script you can do

import mytest
mytest.main(["-x","7","-y","6"]) 

which returns

X center: 7.0
Y center: 6.0