how to execute nested python files - python

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)]

Related

Run another Python script in different folder

How to run another python scripts in a different folder?
I have main program:
calculation_control.py
In the folder calculation_folder, there is calculation.py
How do I run calculation_folder/calculation.py from within calculation_control.py?
So far I have tried the following code:
calculation_file = folder_path + "calculation.py"
if not os.path.isfile(parser_file) :
continue
subprocess.Popen([sys.executable, parser_file])
There are more than a few ways. I'll list them in order of inverted
preference (i.e., best first, worst last):
Treat it like a module: import file. This is good because it's secure, fast, and maintainable. Code gets reused as it's supposed
to be done. Most Python libraries run using multiple methods stretched
over lots of files. Highly recommended. Note that if your file is
called file.py, your import should not include the .py
extension at the end.
The infamous (and unsafe) exec command: execfile('file.py'). Insecure, hacky, usually the wrong answer.
Avoid where possible.
Spawn a shell process: os.system('python file.py'). Use when desperate.
Source: How can I make one python file run another?
Solution
Python only searches the current directory for the file(s) to import. However, you can work around this by adding the following code snippet to calculation_control.py...
import sys
sys.path.insert(0, 'calculation_folder') # Note: if this relavtive path doesn't work or produces errors try replacing it with an absolute path
import calculation

Include/embed python file "as is"

For better code readability, let's suppose that I've got my code logically splitted in different python files, my main main.py file and an included.py file. I'd like to embed included.py inside of the main file.
I know it's possible to import it on main.py (e.g. from included import *), but, in some cases, objects/classes/variables on the main.py file may be imported on the included.py file too (e.g. from main import *).
What I'd like to do is to import the included.py file "as is" (like PHP does, with the include statement) on a specific position of my main.py file, by forcing the interpreter to read the content of the file and to place it on the specified position.
Is it possible?
In Python 2, try the execfile() command:
execfile('included.py')
In Python 3, try
exec(compile(open('included.py', "rb").read(), 'included.py', 'exec'))
I performed a simple test and this seems to work. Does it help in your case?
For more 'traditional' import ways:
https://stackoverflow.com/a/20749411/5172579
For the relation of Python2's execfile() and Python3's exec():
https://stackoverflow.com/a/6357418/5172579
p.s. as noted in the comment: Cyclic imports should be avoided in general and can lead easily to infinite import recursions.

Always import same list at beginning of python script

I have several python scripts that all start with the same set of lines, and I would like to be able to change the lines only once.
For example something like this:
import pickle
import sys
sys.path.append("/Users/user/folder/")
import someOtherModules
x=someOtherModules.function()
I know I could save this as a string, and then load the string and run the exec() command, but I was wondering if there is a better way to do this.
In other words, I want to import a list of modules and run some functions at the beginning of every script.
You can define your own module.
# my_init.py
def init():
print("Initializing...")
And simply add this at the beginning of all your scripts:
import my_init
my_init.init()
Depending on where your scripts and my_init.py are located, you may need to add it to your Python user site directory, see: Where should I put my own python module so that it can be imported
You can move all stuff in separate script and in another scripts import everything from it: from my_fancy_script import *. In this case not only code inside my_fancy_script will be executed but also imports will be pushed to another files.
Anyway, better to use Delgan's answer

Add a module when running a python program from terminal

I wrote a module that, if it is imported, automatically changes the error output of my program. It is quite handy to have it in almost any python code I write.
Thus I don't want to add the line import my_errorhook to every code I write but want to have this line added automatically.
I found this answer, stating that it should be avoided to change the behavior of python directly. So I thought about changing the command line, something like
python --importModule my_errorhook main.py
and defining an alias in the bashrc to overwrite the python command to automatically add the parameter. Is there any way I could achieve such a behavior?
There is no such thing like --importModule in python command line. The only way you can incept the code without explicitly importing is by putting your functions in builtins module. However, this is a practice that is discouraged because it makes your code hard to maintain without proper design.
Let's assume that your python file main.py is the entry point of the whole program. Now you can create another file bootstrap.py, and put below codes into the new file.
import main
__builtins__.func = lambda x: x>=0
main.main()
Then the function func() can be called from all modules without being imported. For example in main.py
def main():
...
print(func(1))
...

Linking Python Files Assistance

I understand how to actually link python files, however, i don't understand how to get variable's from these linked files. I've tried to grab them and I keep getting NameError.
How do I go about doing this? The reason i want to link files is to simply neaten up my script and not make it 10000000000 lines long. Also, in the imported python script, do i have to import everything again? Another question, do i use the self function when using another scripts functions?
ie;
Main Script:
import sys, os
import importedpyfile
Imported Py File
import sys, os
I understand how to actually link python files, however, i don't
understand how to get variable's from these linked files. I've tried
to grab them and I keep getting NameError.
How are you doing that? Post more code. For instance, the following works:
file1.py
#!/usr/bin/env python
from file2 import file2_func, file2_variable
file2_func()
print file2_variable
file2.py:
#!/usr/bin/env python
file2_variable = "I'm a variable!"
def file2_func():
print "Hello World!"
Also, in the imported python script, do i have to import everything
again?
Nope, modules should be imported when the python interpreter reads that file.
Another question, do i use the self function when using another
scripts functions?
Nope, that's usually to access class members. See python self explained.
There is also more than one way to import files. See the other answer for some explanations.
I think what you are trying to ask is how to get access to global vars from on .py file without having to deal with namespaces.
In your main script, replace the call to import importedpyfile to say this instead
from importedpyfile import *
Ideally, you keep the code the way you have it. But instead, just reference those global vars with the importedpyfile namespace.
e.g.
import importedpyfile
importedpyfile.MyFunction() # calls "MyFunction" that is defined in importedpyfile.py
Python modules are not "linked" in the sense of C/C++ linking libraries into an executable. A Python import operation creates a name that refers to the imported module; without this name there is no (direct) way to access another module.

Categories