Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common Python scripts are getting called multiple times

Tags:

python

I have the following project structure.

 - README.rst
 - LICENSE
 - setup.py
 - requirements.txt
 - common_prj/__init__.py
 - common_prj/common_lib.py
 - common_prj/config.xml
 - Project1/__init__.py
 - Project1/some_app_m1.py
 - Project1/some_app_m2.py
 - Project1/some_app.py
 - Project2/some_app1.py

I am having all my common classes in common_prj/common_lib.py file. Now each module file from Project1 is calling common_prj/common_lib.py to access common classes and setup project env using config.xml

#import in some_app_m1.py


from common_prj import common_lib

#import in some_app_m2.py


from common_prj import common_lib

Imports in some_app.py


from Project1 import some_app_m1
from Project1 import some_app_m2 
from common_prj import common_lib
###
  <some functions>
  <some functions>
###
if __name__ == '__main__':

With the above three import it seems common_lib.py is getting executed multiple time , but if I keep the common_lib.py in Project1 then I don't see this issue.

Please let me now how can I keep common_lib.py in common package and call that from Project1 scripts without executing it multiple time. The purpose of common_lib.py is to share common classes with scripts in Project2.

I have the below code in common_lib.py which is repeating for calling classes from each module after import.


self.env = dict_env.get(int(input("Choose Database ENV for this execution : \n" + str(dict_env) + "\nSelect the numeric value => ")))
self.app = dict_app.get(int(input("Choose application for this execution : \n" + str(dict_app) + "\nSelect the numeric value => ")))

My question why I am not facing this issue if I keep common_lib.py in Project1 rather common_prj. I added the above code in common_lib.py because I don't wanted to repeat these lines and ENV setup in my all app code. These are global env settings for all application scripts code inside Project1.


output


Choose Database ENV for this execution : 
{1: 'DEV', 2: 'SIT', 3: 'UAT', 4: 'PROD'}
Select the numeric value => 1
Choose application for this execution : 
{1: 'app1', 2: 'app2', 3: 'app3', 4: 'app4', 5: 'app5', 6: 'app6'}
Select the numeric value => 1
Choose Database ENV for this execution : ### Here it is repeating again from common_lib.py
{1: 'DEV', 2: 'SIT', 3: 'UAT', 4: 'PROD'}
Select the numeric value => 1
Choose application for this execution : ### Here it is repeating again from common_lib.py
{1: 'app1', 2: 'app2', 3: 'app3', 4: 'app4', 5: 'app5', 6: 'app6'}
Select the numeric value => 1
like image 343
Arindam Pal Avatar asked Feb 14 '26 23:02

Arindam Pal


1 Answers

Note: This is my first answer where I answer in-depth of the logistics of python. If I have said anything incorrect, please let me know or edit my answer (with a comment letting me know why). Please feel free to clarify any questions you may have too.


As the comments have discussed if __name__ == '__main__': is exactly the way to go. You can check out the answers on the SO post for a full description or check out the python docs.

In essence, __name__ is a variable for a python file. Its behavior includes:

  • When used in a file, its value is defaulted to '__main__'.
  • When a file imports another program. (import foo). foo.__name__ will return 'foo' as its value.

Now, when importing a file, python compiles the new file completely. This means that it will run everything that can be run. Python compiles all the methods, variables, etc. As it's compiling, if python comes across a callable function (i.e hello_world()) it will run it. This happens even if you're trying to import a specific part of the package or not.

Now, these two things are very important. If you have some trouble understanding the logic, you can take a look at some sample code I created.

Since you are importing from common_prj 3 times (from the some_app_m* file and my_app.py file), you are running the program in common_prj three times (This is also what makes python one of the slower programming languages).

Although I'm unable to see your complete code, I'm assuming that common_prj.py calls common_lib() at some point in your code (at no indentation level). This means that the two methods inside:

self.env = dict_env.get(int(input("Choose Database ENV for this execution : \n" + str(dict_env) + "\nSelect the numeric value => ")))
self.app = dict_app.get(int(input("Choose application for this execution : \n" + str(dict_app) + "\nSelect the numeric value => ")))

were also called.

So, in conclusion:

  1. You imported common_prj 3 times
  2. Which ran common_lib multiple times as well.

Solution:

  • This is where the __name__ part I talked about earlier comes into play
  • Take all callable functions that shouldn't be called during importing, and place them under the conditional of if __name__ == '__name__':
  • This will ensure that only if the common_prj file is run then the condition will pass.

Again, if you didn't understand what I said, please feel free to ask or look at my sample code!

Edit: You can also just remove these callable functions. Files that are meant to be imported use them to make sure that the functions work as intended. If you look at any of the packages that you import daily, you'll either find that the methods are called in the condition OR not in the file at all.

like image 110
12944qwerty Avatar answered Feb 16 '26 12:02

12944qwerty



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!