杰瑞科技汇

Python里如何运行另一个Python脚本?

这是一个非常好的问题,因为它触及了 Python 解释器的工作方式,并引出了一个常见但容易混淆的术语。

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

我们来分两种情况详细解释:

在终端/命令行中运行一个 Python 脚本文件

这是最常见、最标准的用法,当你想执行一个已经写好的 Python 代码文件(my_script.py)时,你会这样做。

步骤:

  1. 打开终端 (在 Windows 上是 PowerShell, CMD, 或 Git Bash;在 macOS/Linux 上是 Terminal)。
  2. 导航到你的 Python 文件所在的目录,使用 cd 命令。
    # 如果你的文件在桌面的 my_project 文件夹里
    cd Desktop/my_project
  3. 使用 python 命令来运行文件
    python my_script.py

工作原理:

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

这里的第一个 python指令,它告诉你的操作系统:“请启动 Python 解释器程序”,第二个 my_script.py参数,它被传递给刚刚启动的 Python 解释器,解释器会读取 my_script.py 文件中的代码,然后一行一行地执行它。

示例:

假设你有一个名为 hello.py 的文件,内容如下:

# hello.py
print("Hello from Python script!")
name = input("What's your name? ")
print(f"Nice to meet you, {name}!")

在终端中运行它:

Python里如何运行另一个Python脚本?-图3
(图片来源网络,侵删)
$ python hello.py

输出:

Hello from Python script!
What's your name? Alice
Nice to meet you, Alice!

在 Python 代码中运行 Python 代码(动态执行)

这是一种更高级的用法,通常用于需要在程序运行时动态地生成并执行 Python 代码的场景,这被称为“动态执行”或“反射”。

主要有两种方式实现:

eval() 函数

eval() 函数会计算一个字符串表达式,并返回结果。

适用场景: 简单的、单行的数学或逻辑表达式。

示例:

# 定义一个字符串形式的数学表达式
expression = "10 + (5 * 3)"
# 使用 eval() 来执行这个字符串
result = eval(expression)
print(f"表达式 '{expression}' 的结果是: {result}")

输出:

表达式 '10 + (5 * 3)' 的结果是: 25

⚠️ 安全警告: eval() 非常危险!因为它会执行字符串中的任何 Python 代码,如果字符串内容来自不可信的用户(例如网页输入框),他们可以注入恶意代码,删除你的文件等。

危险示例:

# 绝对不要对不可信的输入使用 eval()
malicious_code = "__import__('os').system('echo 你被黑了!')" # 在 Linux/macOS 上
# malicious_code = "__import__('os').system('echo 你被黑了 & pause')" # 在 Windows 上
eval(malicious_code) # 这行代码会执行系统命令!

exec() 函数

exec() 函数会执行一个字符串形式的代码块(可以包含多行语句、定义函数、类等)。

适用场景: 复杂的、多行的 Python 代码。

示例:

# 定义一个多行的 Python 代码字符串
code_block = """
def greet(name):
    return f"Hello, {name}!"
# 调用这个新定义的函数
message = greet("World")
print(message)
"""
# 使用 exec() 来执行这个代码块
exec(code_block)

输出:

Hello, World!

⚠️ 安全警告: exec()eval() 一样,具有同样的安全风险,它也会执行任何传入的字符串代码,绝不能对不可信的来源使用。


总结与对比

特性 python my_script.py (终端运行) exec() / eval() (代码中运行)
目的 执行一个独立的、已存在的 .py 文件。 在程序运行时动态执行一段代码字符串。
输入 一个文件路径。 一个包含 Python 代码的字符串。
代码来源 程序员预先编写好的静态文件。 可以是程序内部生成的,也可以是用户输入的。
安全性 ,执行的是你自己的文件。 极低,如果字符串来源不可信,有严重安全风险。
常见用途 运行应用程序、脚本、测试等。 动态配置、插件系统、代码生成、数据分析中的动态表达式等。

如何安全地使用 execeval

如果你确实需要动态执行代码,并且希望限制它的权限,可以使用 restrict 关键字(Python 3.8+)来创建一个受限的命名空间。

示例:

# 一个来自不可信源的代码字符串
untrusted_code = "a = 10; b = 20; print(f'计算结果: {a + b}')"
# 创建一个受限的命名空间,防止代码访问全局或本地变量
safe_namespace = {}
try:
    # 将代码限制在 safe_namespace 这个“沙箱”里执行
    exec(untrusted_code, safe_namespace)
    print("代码执行成功。")
    # 你可以从命名空间中获取变量
    # print(f"沙箱中的变量 a: {safe_namespace.get('a')}") # 输出: 10
except Exception as e:
    print(f"执行代码时出错: {e}")
# 尝试访问沙箱外的变量会失败
# print(safe_namespace['a']) # 可以访问
# print(a) # NameError: name 'a' is not defined

一个有趣的“在 Python 里运行 python”的例子:subprocess

你可能想在你的 Python 程序里启动一个全新的、独立的 Python 进程,这可以通过 subprocess 模块实现。

import subprocess
# 启动一个新的 Python 解释器进程,并让它执行一段代码
command = "python -c \"print('这是另一个独立的 Python 进程!'); print(2 + 2)\""
# 使用 subprocess.run 来执行命令
subprocess.run(command, shell=True)
print("主进程继续执行...")

输出:

这是另一个独立的 Python 进程!
4
主进程继续执行...
  • python my_script.py:这是标准的、日常的运行 Python 脚本的方式。
  • exec() / eval():这是强大的、但危险的动态执行工具,适用于特定的高级场景,使用时必须极度小心。
  • subprocess:用于在程序中启动一个全新的、外部的 Python 进程。
分享:
扫描分享到社交APP
上一篇
下一篇