I am new to python and trying to create a module that would fetch a specific variable from an active module preferably as read only. I have tried importing the file in test2 but the print statement displays the length as 0. Cant understand why it is not able to get the current status of the variable and only reading the initialization.
Below is what I have tried, any help would be greatly appreciated.
Thanks.
test1.py
from datetime import datetime,timedelta
import time
data=[]
stop=datetime.now()+timedelta(minutes=5)
while datetime.now()<stop:
time.sleep(1)
data.append(datetime.now().time())
test2.py:
from test1 import *
print len(data)
When you wrap statements in:
if __name__ == "__main__"
The code within only gets executed when you execute that specific module from the Python interpreter. So your Main function won't get executed, and consequently your data variable won't be initialized, unless you run:
python test2.py
You can actually just remove that clause and it will work as expected.
Related
So, I'm quite new to python, and I tried to import a function that I had written in one of my files into another file that I was working on.
Here is the code in the file that I'm trying to import the function from:
def print_me(x):
return 2 * x
print(print_me(5))
Here is the code in my other file:
from question2 import print_me
print(print_me(5))
Now when I run my second file, the answer (10) gets printed twice.
I want to know the reason why my print function in my first file (from which I imported my function) also gets executed.
When import a module, in fact you're importing the whole codes from that file, including print statements and others.
In order to reach this, you should either remove print statement in the first file where you define print_me function, or add this code to your file:
if __name__ == "__main__":
# your code goes here
Have Fun :)
When you import a file, every statement in this file is executed. Therefore both the def statement and the print function call are executed, printing "10" once. Then the code from your other file is executed, printing "10" a second time.
The proper way to deal with this issue is to put all the code that shouldn't be executed on import inside this block:
if __name__ == "__main__":
# code that should not be executed on import
This ensures that the code from the first file is only executed when run.
main.py
#main.py
import main
print('Hello')
Output:
Hello
Hello
I believe that when it comes to the line import main, at that time, main is registered in sys.modules and hence the import statement of another script - which I believe, is not a part of __main__ - is not executed. Can someone please tell me whether I understand it correctly? If not, please give an explanation.
Let's add a little debugging output:
import sys
print([key for key in sys.modules.keys() if 'main' in key])
import main
It prints:
['__main__']
['__main__', 'main']
Why is that?
If you run a module it will not be added as its modules name to sys.modules. Instead it will always be __main__.
If you then import the module by its name (main). That name is not present in sys.modules and as the result the module will be imported again, its code executed and the modules stored in sys.modules under its name.
On executing main.py it will print ['__main__'] and on the re-import it will print both module names: ['__main__', 'main'].
This implies one rule: try not to import the module you are running anywhere in your code.
It only prints it twice because a module is only actually loaded once. This prevents possible unbound recursion. So your print statement gets executed once by the imported module and once by the main program.
Since you're importing main inside main the print statement is executed twice,thats how python works
I know that when we do 'import module_name', then it gets loaded only once, irrespective of the number of times the code passes through the import statement.
But if we move the import statement into a function, then for each function call does the module get re-loaded? If not, then why is it a good practice to import a module at the top of the file, instead of in function?
Does this behavior change for a multi threaded or multi process app?
It does not get loaded every time.
Proof:
file.py:
print('hello')
file2.py:
def a():
import file
a()
a()
Output:
hello
Then why put it on the top?:
Because writing the imports inside a function will cause calls to that function take longer.
I know that when we do 'import module_name', then it gets loaded only once, irrespective of the number of times the code passes through the import statement.
Right!
But if we move the import statement into a function, then for each function call does the module get re-loaded?
No. But if you want, you can explicitly do it something like this:
import importlib
importlib.reload(target_module)
If not, then why is it a good practice to import a module at the top of the file, instead of in function?
When Python imports a module, it first checks the module registry (sys.modules) to see if the module is already imported. If that’s the case, Python uses the existing module object as is.
Even though it does not get reloaded, still it has to check if this module is already imported or not. So, there is some extra work done each time the function is called which is unnecessary.
It doesn't get reloaded after every function call and threading does not change this behavior. Here's how I tested it:
test.py:
print("Loaded")
testing.py:
import _thread
def call():
import test
for i in range(10):
call()
_thread.start_new_thread(call, ())
_thread.start_new_thread(call, ())
OUTPUT:
LOADED
To answer your second question, if you import the module at the top of the file, the module will be imported for all functions within the python file. This saves you from having to import the same module in multiple functions if they use the same module.
Is it possible to import a Python script into a main script and then just use the variables? I don't want the other script to execute inside of the main script, just attach one of the variables...
If you can edit the script being imported, there's a solution:
Put all the executed code into a block starting with
if __name__ == '__main__':
In this way, the code in the if block above will be executed only if the script is run directly. i.e. when you run python script.py.
You can import only the variable like this:
from script import var
If you want to import the variable without going through the whole script, then as per Python's design it's not possible. import will always go through the whole script being imported, and will avoid whatever that's inside __name__ == '__main__'.
You have an option to read the script file and find the variables, then do it yourself by parsing and executing it, but IMO that's unnecessary job to do since you have import.
You can see the answers under Python: import module without executing script
How do I use variables that exist in the main program in the side program? For example, if I were to have Var1 in the main program, how would I use it in the side program, how would I for example, print it?
Here's what I have right now:
#Main program
Var1 = 1
#Side program
from folder import mainprogram
print(mainprogram.Var1)
This I think would work, if it didn't run the main program when it imports it, because I have other functions being executed in it. How would I import all the main program data, but not have it execute?
The only thing I thought of was to import that specific variable from the program, but I don't know how to do it. What I have in my head is:
from folder import mainprogram
from mainprogram import Var1
But it still excecutes mainprogram.
Your approach is basically correct (except for from folder import mainprogram - that looks a bit strange, unless you want to import a function named mainprogram from a Python script named folder.py). You have also noticed that an imported module is executed on import. This is usually what you want.
But if there are parts of the module that you only want executed when it's run directy (as in python.exe mainprogram.py) but not when doing import mainprogram, then wrap those parts of the program in an if block like this:
if __name__ == "__main__":
# this code will not be run on import