杰瑞科技汇

Python脚本如何运行另一个Python程序?

subprocess 模块 (最推荐、最强大)

这是最现代、最灵活、也是最推荐的方法,它旨在替代旧的 os.system()os.spawn*() 函数,你可以完全控制子进程的输入、输出、错误流,并且可以检查其返回码。

Python脚本如何运行另一个Python程序?-图1
(图片来源网络,侵删)

运行一个简单的脚本,不关心输出

如果你想运行一个脚本并等待它完成,但不关心它的输出内容,只需要知道它是否成功。

# script_to_run.py
print("Hello from the other script!")
print("This script is running now.")
# main_script.py
import subprocess
import sys
try:
    # 使用 run() 函数,简单直接
    # [sys.executable, "script_to_run.py"] 确保使用当前 Python 解释器来运行
    result = subprocess.run([sys.executable, "script_to_run.py"], 
                            check=True,  # 如果返回码非零,则抛出 CalledProcessError
                            capture_output=True, # 捕获标准输出和标准错误
                            text=True)         # 将输出解码为文本
    print("--- 子程序执行成功 ---")
    print(f"返回码: {result.returncode}")
    print(f"标准输出:\n{result.stdout}")
    # print(f"标准错误:\n{result.stderr}") # 如果有错误信息,可以在这里查看
except subprocess.CalledProcessError as e:
    print(f"--- 子程序执行失败! ---")
    print(f"返回码: {e.returncode}")
    print(f"标准输出:\n{e.stdout}")
    print(f"标准错误:\n{e.stderr}")

运行脚本并传递参数

你可以像在命令行中一样,向子程序传递参数。

# script_with_args.py
import sys
print(f"脚本接收到的参数数量: {len(sys.argv)}")
for i, arg in enumerate(sys.argv):
    print(f"参数 {i}: {arg}")
# main_script_args.py
import subprocess
import sys
# 准备命令和参数
command = [sys.executable, "script_with_args.py", "arg1", "arg2", "--option"]
# 运行
result = subprocess.run(command, capture_output=True, text=True)
print("--- 子程序执行结果 ---")
print(result.stdout)

运行一个函数 (通过临时文件)

subprocess 主要用于运行独立的程序文件,如果你想运行另一个脚本中的某个函数,一个常见的方法是:

  1. 将要运行的函数代码写入一个临时 .py 文件。
  2. 使用 subprocess 运行这个临时文件,并传递函数名和参数作为命令行参数。
  3. 在临时文件中,解析参数并调用相应的函数。

这是一个高级用法,但非常强大。

Python脚本如何运行另一个Python程序?-图2
(图片来源网络,侵删)
# main_script_function.py
import subprocess
import sys
import tempfile
import os
# 假设这是你想在另一个进程中运行的函数
def my_function(name, times=1):
    print(f"Hello, {name}! This function is running in a separate process.")
    for i in range(times):
        print(f"Count: {i+1}")
# --- 准备工作 ---
# 创建一个临时文件来存放函数代码
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
    temp_script_path = f.name
    # 写入函数定义
    f.write("""
def my_function(name, times=1):
    print(f"Hello, {name}! This function is running in a separate process.")
    for i in range(times):
        print(f"Count: {i+1}")
if __name__ == "__main__":
    import sys
    # 从命令行参数解析函数名和参数
    func_name = sys.argv[1]
    args = sys.argv[2:]
    # 调用函数
    if func_name == 'my_function':
        my_function(*args)
    else:
        print(f"Error: Function '{func_name}' not found.")
""")
# --- 运行 ---
print(f"正在从临时文件运行函数: {temp_script_path}")
command = [sys.executable, temp_script_path, "my_function", "Alice", "3"]
subprocess.run(command)
# --- 清理 ---
os.remove(temp_script_path) # 删除临时文件

import 和函数调用 (最直接、最简单)

如果你的目标不是一个独立的程序,而是一个模块(一个 .py 文件),并且你希望它在同一个进程中运行,那么直接导入和调用函数是最佳选择。

注意:这种方法会导入模块并执行其顶层的代码(所有不在函数或类中的代码),如果只想调用特定函数,请确保模块设计良好,将顶层执行代码放在 if __name__ == "__main__": 块中。

# my_module.py
print("模块 my_module 正在被导入...")
# 这是模块级别的变量
module_data = "This is some data"
def greet(name):
    """一个可以在模块外调用的函数"""
    print(f"你好, {name}! 欢迎来自 my_module.")
    return f"Greeting sent to {name}"
if __name__ == "__main__":
    # 这部分代码只在直接运行 my_module.py 时执行
    print("my_module 作为主程序直接运行。")
    greet("World")
# main_script_import.py
# 直接导入模块
import my_module
# 现在可以访问模块中的变量和函数
print("--- 直接调用模块中的函数 ---")
message = my_module.greet("Alice")
print(message)
print(f"--- 访问模块中的变量 ---")
print(f"module_data: {my_module.module_data}")
print("\n--- 直接运行模块 ---")
# 这会执行 my_module.py 中 if __name__ == "__main__": 像命令行一样
# 在 Python 3.5+ 中,推荐使用 runpy 模块
import runpy
runpy.run_path("my_module.py")
# 或者,更简单的方式是:
# import my_module
# if hasattr(my_module, '__main__'):
#     my_module.__main__() # 但这通常不推荐,因为模块不一定有 __main__ 函数

exec()eval() (非常谨慎地使用)

exec() 会执行一个字符串形式的 Python 代码。eval() 会计算一个字符串表达式的值。

警告exec()eval() 存在严重的安全风险。绝对不要用它来执行来自不可信来源(如用户输入、网络请求)的代码,因为它可以执行任何操作,包括删除文件、安装恶意软件等。

# script_to_exec.py
def say_hello():
    print("Hello from exec!")
say_hello()
# main_script_exec.py
import os
# 1. 读取目标脚本的内容
with open("script_to_exec.py", "r", encoding="utf-8") as f:
    script_content = f.read()
# 2. 使用 exec() 执行
print("--- 使用 exec() 执行 ---")
# exec() 会在当前命名空间中执行代码
# 为了隔离,可以传入一个字典作为命名空间
local_namespace = {}
exec(script_content, globals(), local_namespace)
print("执行完毕。")
# 2. 使用 exec() 执行一个字符串
print("\n--- 使用 exec() 执行字符串 ---")
code_string = "x = 10; y = 20; print(f'x + y = {x + y}')"
exec(code_string)
# 3. 使用 eval() 计算一个表达式
print("\n--- 使用 eval() 计算表达式 ---")
expression_string = "x * y"
result = eval(expression_string, globals(), local_namespace)
print(f"计算结果: {result}")

总结与选择建议

方法 优点 缺点 适用场景
subprocess 最强大、最安全,完全隔离进程,控制输入输出,可处理任何命令行程序。 代码稍多,进程间通信(IPC)比函数调用复杂。 推荐的首选,运行独立的脚本、命令行工具、需要隔离环境(如测试、部署)。
import 最简单、最直接,性能高,共享内存,易于调试。 必须在同一个进程中运行,会污染当前命名空间。 目标是一个模块,你想复用其中的函数和类,而不是把它当成一个独立的程序。
exec() / eval() 可以动态执行代码字符串。 极其危险!性能差,难以调试,可读性差。 几乎不推荐使用,仅在非常特殊的情况下,如动态生成和执行用户自定义的、可信的代码片段。

快速决策指南

  • 我想运行一个独立的 .py 文件,就像在命令行里 python script.py 一样。

    • 使用 subprocess,这是最标准、最可靠的方式。
  • 我想在另一个脚本里使用 some_other_script.py 里的某个函数。

    • 使用 import some_other_script,然后调用 some_other_script.my_function()
  • 我想把一段代码字符串当作程序来运行。

    • 避免这样做,如果必须,请确保代码来源绝对可信,并使用 exec()
分享:
扫描分享到社交APP
上一篇
下一篇