在 Python 中调用另一个 Python 脚本(模块)有多种方法,适用于不同的场景,例如简单的代码复用、参数传递、进程管理等,下面我将从最基础到最复杂的场景,为你详细介绍几种常用方法。

直接导入模块 (Import)
这是最基本、最常用的方法,适用于将一个脚本的功能作为模块导入到另一个脚本中使用。
适用场景:
- 你想复用另一个脚本中的函数、类或变量。
- 被调用的脚本是一个库或工具集的一部分。
如何做:
- 确保
my_module.py和main_script.py在同一个目录下,或者my_module.py所在的目录在 Python 的搜索路径中。 - 在
main_script.py中使用import my_module来导入。
示例:

my_module.py (被调用的脚本)
# 这是一个可以被其他脚本导入的模块
def greet(name):
"""一个简单的问候函数"""
print(f"Hello, {name} from my_module!")
def add(a, b):
"""一个加法函数"""
return a + b
# 如果这个脚本被直接运行,而不是被导入,这里的代码会执行
if __name__ == "__main__":
print("This is my_module.py being run directly.")
greet("Direct Caller")
main_script.py (调用者脚本)
# 导入 my_module 模块
import my_module
# 调用模块中的函数
my_module.greet("Alice")
# 使用模块中的函数
result = my_module.add(5, 3)
print(f"The result of add(5, 3) is: {result}")
# 直接访问模块中的变量(如果有的话)
# print(my_module.some_variable)
运行 main_script.py 的输出:
Hello, Alice from my_module!
The result of add(5, 3) is: 8
注意: if __name__ == "__main__": 是一个非常重要的 Python 约定,当脚本被直接运行时,__name__ 的值是 "__main__";当脚本被其他脚本导入时,__name__ 的值是模块名(这里是 "my_module"),上面的 print 语句只在直接运行 my_module.py 时才会执行。

使用 exec() 函数
exec() 函数可以执行存储在字符串或文件中的 Python 代码,这种方法非常灵活,但也要注意其安全风险。
适用场景:
- 动态执行代码,例如代码是从文件或用户输入中读取的。
- 需要在运行时决定执行哪个脚本。
如何做:
使用 exec(open('filename').read()) 来读取并执行整个文件。
示例:
main_script.py (调用者脚本)
script_path = 'my_module.py'
try:
with open(script_path, 'r') as file:
script_code = file.read()
# 执行读取到的代码
exec(script_code)
print("\nExecuted my_module.py successfully.")
except FileNotFoundError:
print(f"Error: The file {script_path} was not found.")
except Exception as e:
print(f"An error occurred: {e}")
运行 main_script.py 的输出:
This is my_module.py being run directly.
Hello, Direct Caller from my_module!
Executed my_module.py successfully.
⚠️ 重要警告:
exec() 会执行任何它接收到的代码,包括恶意代码。绝对不要使用 exec() 来执行不受信任的代码(例如来自网络用户的输入),这会带来严重的安全风险。
使用 subprocess 模块 (推荐用于独立进程)
当你希望将另一个 Python 脚本作为一个独立的进程来运行时,subprocess 模块是最佳选择,这可以隔离环境,避免命名冲突,并且可以捕获脚本的输出。
适用场景:
- 你想完全分离两个脚本的运行环境。
- 需要向被调用的脚本传递命令行参数。
- 需要获取被调用脚本的输出结果(标准输出、标准错误)。
- 被调用的脚本是一个独立的命令行工具。
如何做:
使用 subprocess.run() 是最现代、推荐的方式。
示例:
cli_tool.py (一个简单的命令行工具)
import sys
import argparse
def main():
parser = argparse.ArgumentParser(description="A simple CLI tool.")
parser.add_argument('--name', type=str, default='World', help="The name to greet.")
parser.add_argument('--count', type=int, default=1, help="The number of times to greet.")
args = parser.parse_args()
for _ in range(args.count):
print(f"Hello, {args.name}!")
if __name__ == "__main__":
main()
main_script.py (调用者脚本)
import subprocess
# 场景1: 运行脚本,不关心输出
print("--- Running script without capturing output ---")
subprocess.run(['python', 'cli_tool.py', '--name', 'Bob'])
# 场景2: 运行脚本,并捕获输出
print("\n--- Running script and capturing output ---")
result = subprocess.run(
['python', 'cli_tool.py', '--name', 'Charlie', '--count', '3'],
capture_output=True, # 捕获标准输出和标准错误
text=True # 将输出解码为文本
)
print(f"Return code: {result.returncode}")
print(f"Stdout:\n{result.stdout}")
print(f"Stderr:\n{result.stderr}")
# 检查是否执行成功
if result.returncode == 0:
print("\nThe script executed successfully!")
else:
print("\nThe script failed.")
运行 main_script.py 的输出:
--- Running script without capturing output ---
Hello, Bob!
--- Running script and capturing output ---
Return code: 0
Stdout:
Hello, Charlie!
Hello, Charlie!
Hello, Charlie!
Stderr:
The script executed successfully!
使用 os.system() 函数 (较旧的方式)
这是 subprocess 模块出现之前的方式,功能相对简单,它会在一个子 shell 中执行命令。
适用场景:
- 简单的命令执行,不需要复杂的参数传递或输出捕获。
- 维护旧的代码库。
如何做:
将命令作为一个字符串传递给 os.system()。
示例:
main_script.py (调用者脚本)
import os
print("--- Running script with os.system ---)
# 使用字符串形式执行命令
# 注意引号的使用,以防 shell 解析错误
os.system('python cli_tool.py --name "David"')
运行 main_script.py 的输出:
--- Running script with os.system ---
Hello, David!
注意: os.system() 不如 subprocess 灵活和安全,通常建议在新代码中使用 subprocess。
总结与选择建议
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
import |
代码集成度高,共享内存,效率高,易于调试 | 共享全局命名空间,可能产生副作用 | 代码复用和模块化开发(首选) |
exec() |
极其灵活,可动态执行任意代码 | 安全风险极高,难以调试,性能较差 | 执行可信的、动态生成的代码(非常谨慎使用) |
subprocess |
隔离环境,可传递参数,可捕获输入/输出,功能强大 | 进程间通信开销比 import 大 |
需要独立进程、命令行交互或隔离环境(强烈推荐) |
os.system() |
简单易用 | 功能有限,不灵活,不安全,已过时 | 简单的、一次性的命令执行(不推荐新项目使用) |
- 如果你想在一个脚本中使用另一个脚本的函数和变量,请用
import。 - 如果你想把另一个脚本当作一个独立的程序来运行,并给它传参数、收结果,请用
subprocess。
