Search code examples
pythonmoduleargumentsprogram-entry-point

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


In Python I have a module myModule.py where I define a few functions and a main(), which takes a few command line arguments.

I usually call this main() from a bash script. Now, I would like to put everything into a small package, so I thought that maybe I could turn my simple bash script into a Python script and put it in the package.

So, how do I actually call the main() function of myModule.py from the main() function of MyFormerBashScript.py? Can I even do that? How do I pass any arguments to it?


Solution

  • 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.