- Execute a Script in Python
- Execute a Python Script in Python
- Use of globals and locals
- Python How to run another Python script with arguments
- The called Python script
- Using immport
- Using exec
- How to specify arguments for the called script
- Call a Python script by subprocess
- How to get the absolute path to Python executable in Python
- Capture the return code by subprocess.call
- Capture the return code and output by subprocess.run
Execute a Script in Python
- Execute a Python Script in Python
- Use of globals and locals
This article will talk about how we can use Python to execute yet another python script.
Execute a Python Script in Python
- object : The Python code in string or byte format
- globals : It is an optional argument. It is a dictionary and contains global functions and variables.
- locals : It is an optional argument. It is a dictionary and contains local functions and variables.
Refer to the following code for an example.
file_name = "code.py" content = open(file_name).read() exec(content)
The above code first opens a file in the working directory by the name of code.py , reads its content, stores it inside a variable by the name content , and then passes the read content to the exec() function. The read content is some Python code, and the exec() method will execute that Python code.
If we have some local or global variables, we can store them inside dictionaries and pass them to the executable script. The script will then be able to utilize those variables and run the code. Note that if we use some functions inside the executable script that we have not passed as a global variable, the main program will throw an Exception.
The following code depicts the same.
from random import randint code = "print(randint(1, 6))" exec(code, <>, <>) # Empty globals and locals
Traceback (most recent call last): File "", line 4, in module> File "", line 1, in module> NameError: name 'randint' is not defined
When the globals and locals are not passed to the exec() , the requirements (to run the script) are automatically handled. Python is smart enough to figure out what all variables or functions are needed to run the script. For example, the following code will run perfectly without any error.
from random import randint code = "print(randint(1, 6))" exec(code) # No globals or locals passed
Use of globals and locals
We can create custom functions and imported functions inside the executable script by passing them to the exec() function via globals . As mentioned above, if these dependencies are not found, exceptions will be raised.
Refer to the following code. Here we will define a custom function and import a function from the random package. Then both functions will be passed to the exec() function wrapped inside a dictionary via the globals parameter.
from random import randint def get_my_age(): return 19 globals = "randint": randint, "get_my_age": get_my_age > code = """ print(randint(1, 6)) print(get_my_age()) """ exec(code, globals,)
5 # It can be any number between 1 and 6, both inclusive 19
Right now, these functions have been passed via the globals parameter. We can also pass them through locals . Since the exec function doesn’t accept keyword arguments, we have to pass an empty dictionary for globals and the pass out locals .
from random import randint def get_my_age(): return 19 locals = "randint": randint, "get_my_age": get_my_age > code = """ print(randint(1, 6)) print(get_my_age()) """ exec(code, <>, locals)
2 # It can be any number between 1 and 6, both inclusive 19
Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.
Python How to run another Python script with arguments
Not all Python scripts are expected to be used by another Python script. The Python code could be written without any function and all the statements might be written on the same level.
In some cases, we need to run the script to do the specific job. How can we run it from a Python script?
The called Python script
I prepared the following python script.
# main_check.py import sys def main(): print(f"Hello World! ()--- from main") def sub(): print(f"Hello World! () --- from sub") if __name__ == "__main__": main() sub()
This script is called by another Python file.
Using immport
The python script is easily called by using import.
if __name__ == "__main__": print("--- import ---") import main_check # --- import --- # Hello World! (['src/exec_another_file.py']) --- from sub
Of course, the main func is not called because the python script checks if it’s called as a main script.
Using exec
The next way is to use exec function.
import pathlib as path if __name__ == "__main__": print("--- exec ---") filepath = path.Path(__file__).parent.joinpath("main_check.py") exec(open(filepath).read()) # --- exec --- # Hello World! (['src/exec_another_file.py'])--- from main # Hello World! (['src/exec_another_file.py']) --- from sub
We need to pass the file path to the script. path module should be used to get the absolute path to the script.
Once we get the absolute path, we can read the contents. It can be passed to exec function.
How to specify arguments for the called script
The Python script to be called might require some arguments. How can we specify them in this case? exec() doesn’t have such a property.
A solution is to assign them to sys.argv
print(sys.argv) # ['src/exec_another_file.py'] sys.argv = ["arg1", "arg2"] exec(open(filepath).read()) # Hello World! (['arg1', 'arg2'])--- from main # Hello World! (['arg1', 'arg2']) --- from sub print(sys.argv) # ['arg1', 'arg2']
The arguments are passed correctly but of course, the original arguments are overwritten. The original arguments need to be stored and re-assign in this case.
print(sys.argv) # ['src/exec_another_file.py'] original_argv = sys.argv sys.argv = ["arg1", "arg2"] exec(open(filepath).read()) # Hello World! (['arg1', 'arg2'])--- from main # Hello World! (['arg1', 'arg2']) --- from sub print(sys.argv) # ['arg1', 'arg2'] sys.argv = original_argv print(sys.argv) # ['src/exec_another_file.py']
Call a Python script by subprocess
Another way is to use subprocess. We need to know the absolute path to the Python executable.
How to get the absolute path to Python executable in Python
How can we get it in Python script? Use sys.executable for it.
print(sys.executable) # /usr/local/bin/python
Then, we can somehow run a python script.
Capture the return code by subprocess.call
The first argument is a list. The first parameter is the path to the python executable. The second parameter is the path to the script that we want to run. Add python options to the second parameter if it’s necessary. After the file path, we can specify (maybe) as many arguments as we want.
res = subprocess.call([sys.executable, filepath, "one", "two"]) # Hello World! (['/workspaces/blogpost-python/src/main_check.py', 'one', 'two'])--- from main # Hello World! (['/workspaces/blogpost-python/src/main_check.py', 'one', 'two']) --- from sub print(res) # 0
The specified values are shown in the called python script. subprocess.call returns a return code of the called python script.
Capture the return code and output by subprocess.run
The output of the called python script can’t be used in the caller python script. Use subprocess.run if the output needs to be used in the caller script.
res = subprocess.run([sys.executable, filepath, "one", "two"], capture_output=True, check=False) print(res.returncode) # 0 print(res.stderr) # b'' print(res.stdout) # b"Hello World! (['/workspaces/blogpost-python/src/main_check.py', 'one', 'two'])--- from main\n # Hello World! (['/workspaces/blogpost-python/src/main_check.py', 'one', 'two']) --- from sub\n"
I added a new line for better reading of stdout . print is used in the called python script but it is not written to the console. Instead, it is stored to stdout and the output can be checked in the caller script.