0

I had developed 2 python (3.x) scripts. They each followed some basic flow in the body by calling these methods - process_params() - run(params)

I now have a use case where it is useful for my first python script to call a specific function in my second python script.

So, to prevent name conflicts of process_params() and run(params), I did the following: - Put both files in the same directory. - In my first python script, I have essentially following:

sys.path.append(".")
from script2 import needed_function

To my horror and surprise, when I called "script1", it is invoking script2's process_params() even though I didn't import it!!!

I then attempted to create a small-simple test case to demonstrate this unexpected behavior. However, I failed; the test case return what I expected by using the local process_params()!

That means that there is something really odd (something that I messed up) in my actual code where script1 will call script2's process_params() instead of its own local instance when I had only import a single and different method from script2. Since the problem is probably "unique" to how my actual scripts' code is; but the scripts are long and it has confidential information as well that I cannot post them here. Are there suggestions or theories that anyone can suggest on how I approach this problem?

chowsai
  • 565
  • 3
  • 15
Chung Ley
  • 29
  • 1
  • 7
  • You probably have the function being called in script2. – cs95 Sep 12 '17 at 23:52
  • Are you relying on module-level variables inside your `needed_function`? – juanpa.arrivillaga Sep 12 '17 at 23:54
  • 2
    You don't have to disclose private code or data to post a good question. Actually, you're even encouraged to strip all that's irrelevant by making a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) and post it here. You might also have a look at [“what does `if __name__ == "__main__"` do?”](https://stackoverflow.com/questions/419163/what-does-if-name-main-do), which could by your issue. – spectras Sep 12 '17 at 23:55
  • 4
    When you import a module, ALL of it gets executed even if you are importing only one thing from it. Use an `if __name__ == "__main__"` guard to make module-level statements execute only that file is called as the "main" script. – kindall Sep 12 '17 at 23:56
  • Thank you all.... Yes, I totally forgot about using the if __name__ == "__main__"; this makes sense. This is so obvious now. Damn. – Chung Ley Sep 13 '17 at 04:47

1 Answers1

1

You are likely calling process_params from the module level.

The following shows the behavior you are describing

s1.py

from s2 import needed_function
def foo():
    print("Script 1 foo() called")


foo()
needed_function()

s2.py

def needed_function():
    print("needed_function called")

def foo():
    print("Script 2 foo() called")

foo()

Which, when I run s1.py, prints the following

$ python s1.py 
Script 2 foo() called
Script 1 foo() called
needed_function called

You need to check for __name__ == "__main__" to guard your calls. Whenever the module is imported, __name__ will contain the module name. Only when it's the module that is run directly will it be __main__.

So, slight modifications give

# s3.py
from s4 import needed_function
def foo():
    print("Script 3 foo() called")


if __name__ == "__main__":
    foo()
    needed_function()from s4 import needed_function
def foo():
    print("Script 3 foo() called")


if __name__ == "__main__":
    foo()
    needed_function()

# s4.py
def needed_function():
    print("needed_function called")

def foo():
    print("Script 4 foo() called")


if __name__ == "__main__":
    foo()

and, likely, the desired results

$ python s3.py 
Script 3 foo() called
needed_function called
kdopen
  • 8,032
  • 7
  • 44
  • 52