How to call a script from another script?
Categories:
Mastering Script Execution: Calling One Python Script from Another

Learn various methods to execute a Python script from within another, understanding their implications for process control, data sharing, and environment management.
In Python development, it's a common requirement to organize code into modular scripts and then execute one script from within another. This approach promotes code reusability, improves project structure, and allows for complex workflows to be broken down into manageable components. This article explores several robust methods for calling a Python script from another, detailing their use cases, advantages, and potential pitfalls.
Understanding the Need for Inter-Script Communication
Before diving into the 'how,' it's crucial to understand 'why' you might need one script to call another. Common scenarios include:
- Modularity: Breaking down a large application into smaller, focused scripts.
- Workflow Orchestration: A main script coordinating the execution of several sub-tasks.
- Resource Management: Running a script that sets up an environment, then executing another that performs the core logic.
- Testing: Automating the execution of test scripts from a test runner.
flowchart TD A[Main Script] --> B{"Call Method?"} B -->|Import| C[Sub-script as Module] B -->|Subprocess| D[Sub-script as Separate Process] B -->|Exec/Popen| E[Sub-script as External Command] C --> F[Function/Class Call] D --> G[Independent Execution] E --> H[Shell Command Execution] F & G & H --> I[Result/Output]
Decision flow for calling one Python script from another.
Method 1: Importing as a Module
The most Pythonic and generally recommended way to reuse code from another script is to treat it as a module. This involves importing the script and then calling its functions or accessing its variables directly. For this to work effectively, the called script should be designed with functions or classes that encapsulate its logic, rather than having top-level executable code.
# sub_script.py
def greet(name):
return f"Hello, {name}!"
def calculate_sum(a, b):
return a + b
if __name__ == "__main__":
print("This code runs only when sub_script.py is executed directly.")
print(greet("World"))
Example of sub_script.py
designed for modular import.
# main_script.py
import sub_script
message = sub_script.greet("Alice")
print(message)
result = sub_script.calculate_sum(10, 20)
print(f"The sum is: {result}")
Calling sub_script.py
as a module from main_script.py
.
if __name__ == "__main__":
block in your sub-scripts to prevent code meant for direct execution from running when the script is imported as a module.Method 2: Using subprocess
Module
When you need to run another script as a completely separate process, perhaps to isolate its environment, capture its output, or run it concurrently, the subprocess
module is the ideal choice. This method treats the called script as an external command, similar to running it from the command line. It's particularly useful for running scripts that are not designed as modules or for executing scripts written in other languages.
# another_script.py
import sys
if len(sys.argv) > 1:
name = sys.argv[1]
print(f"Hello from another_script.py, {name}!")
else:
print("Hello from another_script.py!")
print("This is some output from another_script.py.")
Example of another_script.py
that accepts command-line arguments.
# main_caller.py
import subprocess
import sys
# Method 1: Simple call, waits for completion
print("\n--- Calling another_script.py without arguments ---")
subprocess.run([sys.executable, 'another_script.py'])
# Method 2: Calling with arguments and capturing output
print("\n--- Calling another_script.py with arguments and capturing output ---")
result = subprocess.run(
[sys.executable, 'another_script.py', 'Bob'],
capture_output=True, text=True, check=True
)
print("STDOUT:", result.stdout)
print("STDERR:", result.stderr)
# Method 3: Running in the background (non-blocking)
print("\n--- Calling another_script.py in the background ---")
process = subprocess.Popen([sys.executable, 'another_script.py', 'Charlie'])
# Do other things while another_script.py runs
# process.wait() # Uncomment to wait for completion
print("Main script continues execution...")
Using subprocess.run
and subprocess.Popen
to execute another script.
subprocess
, be mindful of security implications if you're executing user-provided input. Always sanitize inputs to prevent command injection vulnerabilities.Method 3: Using exec()
or execfile()
(Python 2)
The exec()
function (and execfile()
in Python 2) allows you to execute Python code dynamically. While powerful, it's generally discouraged for calling other scripts due to security risks and difficulty in debugging. It executes the code in the current namespace, which can lead to unexpected variable overwrites or scope issues. Use this method with extreme caution and only when other options are not viable.
# dynamic_script.py
my_variable = "I am from dynamic_script.py"
def dynamic_function():
print("Hello from dynamic_function!")
A simple script to be executed dynamically.
# main_dynamic_caller.py
# This method is generally discouraged for inter-script calls.
print("Before exec:")
try:
print(my_variable) # This will raise a NameError
except NameError as e:
print(f"Error: {e}")
with open('dynamic_script.py', 'r') as f:
code = f.read()
exec(code)
print("\nAfter exec:")
print(my_variable)
dynamic_function()
Demonstrating exec()
to run another script's content.
exec()
for general script calling. It can introduce security vulnerabilities (especially with untrusted input) and make code harder to maintain and debug due to its dynamic nature and impact on the current execution scope.