0

I am writing a Python (3.5) module in which I'd like to make use of an existing Python module from an open source project. The module I want to import contains:

  • several functions
  • a if __name__ == '__main__': instruction

but does not contain a def main(args) function.

Because there is no actual main function, I cannot import it by means of import module and use it as module.main(). Although I did find options to separately execute it as script via the commands os.system() and subprocess.Popen(), I am actually looking for a way to make this call an integral part of my code.

I understand I can add the def main() part myself in the original code, but because it comes from an open source project, I am looking for ways to leave it untouched, so that I don't need to maintain it myself if it gets updated.

I have gone through other very similar questions, such as this and this that could not solve my issue. This answer gives me the feeling what I am trying to do is not trivial.

Is there any way to do this?

raggot
  • 992
  • 15
  • 38
  • 1
    In theory, you could write some sort of nasty import hook that rewrites the ast to turn `if __name__ == '__main__'` into a function. In practice, this is probably a recipe for really weird bugs and maintenance nightmares. Have you considered just submitting a pull request to add a `main` function? – user2357112 May 11 '18 at 20:25
  • 1
    If the module is written that way, it's entirely possible that the author considers the code inside the `if __name__ == '__main__':` block to be module initialization code that must not be run more than once. – Larry Lustig May 11 '18 at 20:45
  • @LarryLustig, that might be actually true. I was hoping to find a large shortcut and pick-up existing code as much as possible, but if I think it that way, I might not be doing the right thing if I called _that_ script/function all the time. – raggot May 11 '18 at 22:56

1 Answers1

2

When you import a module for the first time, (as distinguished from importing a function), all code in that module executes. That means functions become defined, global variables become defined, etc. The reason we write an if __name__ == "__main__": block is so that when importing a module, that code does not execute (it will only execute if name == "main"). If you simply remove the if __name__ == "__main__": line and fix the indentation, that code will execute when you import the module. take this module hello.py for example:

def hello_world():
    print("Hello world")
if __name__ == "__main__":
    hello_world()

then if we import:

import hello
hello_world()

The code below will do the same thing as this case where the first module is again hello.py:

def hello_world():
    print("hello world")
hello_world()

module to be executed:

import hello

I recommend you do not do it this way though, you really should just edit to include a main function.

ChootsMagoots
  • 670
  • 1
  • 6
  • 19
  • First, it won't execute every time you import the module; it'll only execute the first time (per Python process). Second, the questioner does not want to edit the file. Third, even for solutions that involve editing the file, adding a `main` function is a better way. – user2357112 May 11 '18 at 20:27
  • I've corrected my answer re your first point, I didn't notice your second point, and I always agreed with, but have edited to explicate your third. – ChootsMagoots May 11 '18 at 20:30