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.
Related
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.
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.
I'm using python 2.7, the following is the simplified version of my script:
executor.py
import sys
def someCal(num):
num = int(num)
print num*num
someCal(sys.argv[1])
so python executor.py 13 would print out 169, it's working as expected.
and I have another script, I want to make use of someCal() function in executor.py so I import it
main.py
import executor
to_count = 999
executor.someCal(to_count)
I got the error message below when execute python main.py:
File "main.py", line 3, in <module>
import executor
File "/Users/mac/executor.py", line 13, in <module>
someCal(sys.argv[1])
I don't know why it keep mentioning about line 13 in executor.py, because I didn't use that part.
Thanks in advance!
from executor import *
It is a better method and will work fine as you wanted.No need if name == 'main': with this method. Also you can call your functions with their names.Like:
from executor import *
print (someCal(10))
Edit for example:
executor.py
def someCal(num):
num = int(num)
return num*num
another.py
from executor import *
print (someCal(10))
Output:
>>>
100
>>>
If you working with functions, you should return a value in function, not print. If you return a value, you can print it later.But if you dont use return and just keep it like print num*num, then you cant use it later with print function. You can try and see that.So, returning a value is important in functions.
For your second question, check this one: What does if __name__ == "__main__": do?
Python is the best language about clear codes, so you should keep it clear, sys is not necessary for you. And you dont need if name == 'main': this statement, remember every .py file is a module, so if you can import any module without that statement,like import random; then you can import your own modules too.Just care about they have to stay in same directory so Python can find your own module/file. Keep it simple :-)
Another import method for a module is:
import executor as ChuckNorris
print (ChuckNorris.someCal(10))
Output is same of course, you can write whatever you want instead of ChuckNorris, but be sure that name doesnt overlap with another function name in your program. For example you have a .py file called Number.py, you will import this file to another file, but you cant be sure is there any function called Number in another one, so you can call it like import Number as whatyouwanttocallit and you will avoid from that problems.
When you import executor in main.py, it actually doing python executor.py, I suggest you change your executor.py to:
if __name__ == '__main__':
someCal(sys.argv[1])
and, you might want to add defensive code like if len(sys.argv)>1 before use sys.argv[1] directly
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
I have 3 python files.(first.py, second.py, third.py) I'm executing 2nd python file from the 1st python file. 2nd python file uses the 'import' statement to make use of 3rd python file. This is what I'm doing.
This is my code.
first.py
import os
file_path = "folder\second.py"
os.system(file_path)
second.py
import third
...
(rest of the code)
third.py (which contains ReportLab code for generating PDF )
....
canvas.drawImage('xyz.jpg',0.2*inch, 7.65*inch, width=w*scale, height=h*scale)
....
when I'm executing this code, it gives error
IOError: Cannot open resource "xyz.jpg"
But when i execute second.py file directly by writing python second.py , everything works fine..!!
Even i tried this code,
file_path = "folder\second.py"
execfile(file_path)
But it gives this error,
ImportError: No module named third
But as i stated everything works fine if i directly execute the second.py file. !!
why this is happening? Is there any better idea for executing such a kind of nested python files?
Any idea or suggestions would be greatly appreciated.
I used this three files just to give the basic idea of my structure. You can consider this flow of execution as a single process. There are too many processes like this and each file contains thousandth lines of codes. That's why i can't change the whole code to be modularize which can be used by import statement. :-(
So the question is how to make a single python file which will take care of executing all the other processes. (If we are executing each process individually, everything works fine )
This should be easy if you do it the right way. There's a couple steps that you can follow to set it up.
Step 1: Set your files up to be run or imported
#!/usr/bin/env python
def main():
do_stuff()
if __name__ == '__main__':
The __name__ special variable will contain __main__ when invoked as a script, and the module name if imported. You can use that to provide a file that can be used either way.
Step 2: Make your subdirectory a package
If you add an empty file called __init__.py to folder, it becomes a package that you can import.
Step 3: Import and run your scripts
from folder import first, second, third
first.main()
second.main()
third.main()
The way you are doing thing is invalid.
You should: create a main application, and import 1,2,3.
In 1,2,3: You should define the things as your functions. Then call them from the main application.
IMHO: I don't need that you have much code to put into separate files, you just also put them into one file with function definitions and call them properly.
I second S.Lott: You really should rethink your design.
But just to provide an answer to your specific problem:
From what I can guess so far, you have second.py and third.py in folder, along with xyz.jpg. To make this work, you will have to change your working directory first. Try it in this way in first.py:
import os
....
os.chdir('folder')
execfile('second.py')
Try reading about the os module.
Future readers:
Pradyumna's answer from here solved Moin Ahmed's second issue for me:
import sys, change "sys.path" by appending the path during run
time,then import the module that will help
[i.e. sys.path.append(execfile's directory)]