杰瑞科技汇

Python如何调用文件中的Python代码?

下面我将详细介绍这几种方法,并提供清晰的示例和适用场景分析。

Python如何调用文件中的Python代码?-图1
(图片来源网络,侵删)

场景设定

我们假设有两个文件,它们都在同一个目录下:

  1. main_script.py (我们将要执行这个文件)
  2. helper_module.py (这个文件包含了我们想要使用的代码)

helper_module.py (被调用的文件)

这个文件里定义了一些函数和变量。

# helper_module.py
# 一个简单的函数
def greet(name):
    """向某人问好"""
    print(f"你好, {name}! 欢迎来自 helper_module.py 的问候。")
# 一个计算函数
def add(a, b):
    """返回两个数的和"""
    return a + b
# 一个模块级别的变量
MODULE_VERSION = "1.0"

导入 (Import) - 最常用、最规范的方法

这是Python中最推荐、最规范的方式,它将目标文件作为一个模块导入到当前命名空间中,然后你就可以像使用普通库一样使用它的函数和变量。

核心思想: 将代码作为“模块”或“库”来使用。

Python如何调用文件中的Python代码?-图2
(图片来源网络,侵删)

如何操作:

main_script.py 中,使用 import 语句。

# main_script.py
# 方式1: 导入整个模块
import helper_module
# 使用模块名.函数名 的方式调用
helper_module.greet("小明")
# 使用模块名.变量名 的方式访问
print(f"helper_module 的版本是: {helper_module.MODULE_VERSION}")
# 方式2: 导入特定的函数或变量 (更简洁)
from helper_module import add, MODULE_VERSION
# 直接使用函数名和变量名,无需模块名前缀
result = add(10, 5)
print(f"10 + 5 的结果是: {result}")
print(f"再次确认版本: {MODULE_VERSION}")

如何运行: 在终端中,直接运行 main_script.py

python main_script.py

输出结果:

你好, 小明! 欢迎来自 helper_module.py 的问候。
helper_module 的版本是: 1.0
10 + 5 的结果是: 15
再次确认版本: 1.0

使用 exec() 函数 - 动态执行代码块

exec() 是一个内置函数,它会动态地执行一个字符串形式的Python代码,你可以把整个文件的内容读出来,然后交给 exec() 去执行。

Python如何调用文件中的Python代码?-图3
(图片来源网络,侵删)

核心思想: 将文件内容作为字符串代码来执行。

如何操作:

# main_script.py
# 读取 helper_module.py 的全部内容
with open('helper_module.py', 'r', encoding='utf-8') as f:
    code = f.read()
# 使用 exec() 执行这段代码
# 注意:exec() 会将代码在当前命名空间中执行
# 这意味着 helper_module.py 中定义的函数和变量会直接进入 main_script.py 的全局作用域
exec(code)
# 现在你可以直接使用 helper_module.py 中定义的函数和变量
greet("小红")
print(f"通过 exec() 执行后,add(20, 30) = {add(20, 30)}")

如何运行:

python main_script.py

输出结果:

你好, 小红! 欢迎来自 helper_module.py 的问候。
通过 exec() 执行后,add(20, 30) = 50

⚠️ 重要警告: exec() 会执行任何给定的代码,如果文件内容来自不可信的来源(比如用户上传的文件),这会带来严重的安全风险(代码注入攻击)。永远不要对不可信的源使用 exec()


使用 subprocess 模块 - 启动新的独立进程

这种方法会像在命令行中输入 python helper_module.py 一样,启动一个全新的、独立的Python进程来运行目标文件,两个脚本之间默认是隔离的,不能直接共享变量。

核心思想: 将另一个Python脚本当作一个独立的程序来运行。

如何操作:

helper_module.py 需要能独立运行,我们通常在它里面加一段 if __name__ == "__main__": 的代码。

修改 helper_module.py

# helper_module.py
def greet(name):
    print(f"你好, {name}! 欢迎来自 helper_module.py 的问候。")
def add(a, b):
    return a + b
MODULE_VERSION = "1.0"
# --- 新增的代码 ---
# 这部分代码只有在文件被直接执行时才会运行
if __name__ == "__main__":
    print("--- helper_module.py 开始独立运行 ---")
    greet("世界")
    print("--- helper_module.py 独立运行结束 ---")

main_script.py 的内容:

# main_script.py
import subprocess
# 使用 subprocess.run() 来执行另一个脚本
# 注意:这里需要传入一个列表,第一个元素是解释器,第二个是脚本文件名
print("--- main_script.py 准备调用 helper_module.py ---")
result = subprocess.run(['python', 'helper_module.py'])
print("\n--- helper_module.py 已经执行完毕 ---")
print(f"子进程的返回码是: {result.returncode}") # 0 表示成功

如何运行:

python main_script.py

输出结果:

--- main_script.py 准备调用 helper_module.py ---
--- helper_module.py 开始独立运行 ---
你好, 世界! 欢迎来自 helper_module.py 的问候。
--- helper_module.py 独立运行结束 ---
--- helper_module.py 已经执行完毕 ---
子进程的返回码是: 0

直接作为脚本运行 (使用 __import__importlib)

这种方法和方法一(import)非常相似,它提供了更底层的、动态的模块导入方式,通常在高级编程或元编程中使用,而不是日常编码。

如何操作:

# main_script.py
# 方法一:使用内置的 __import__ 函数 (不推荐直接使用,语法较复杂)
# module = __import__('helper_module')
# module.greet("通过 __import__")
# 方法二:使用标准库 importlib (更推荐和标准)
import importlib
# 动态导入模块
helper_module = importlib.import_module('helper_module')
# 使用导入的模块
helper_module.greet("通过 importlib")

如何运行:

python main_script.py

输出结果:

你好, 通过 importlib! 欢迎来自 helper_module.py 的问候。

总结与对比

方法 核心思想 优点 缺点 适用场景
import 将文件作为模块导入 最规范、最安全,代码结构清晰,易于维护和复用 需要模块在 PYTHONPATH 中或与脚本同目录 99% 的情况,构建大型应用、库、项目时
exec() 动态执行文件中的代码字符串 灵活性极高,可以动态执行任意代码 有安全风险,污染当前命名空间,调试困难 动态代码生成、运行时动态加载(确保代码来源可信)
subprocess 启动一个新的独立进程 隔离性好,可以调用不同Python版本的脚本,能获取脚本的标准输出 进程间通信复杂,性能开销大 需要将另一个脚本作为独立任务运行;需要其标准输出时
importlib 动态地导入模块 __import__ 更清晰,是官方推荐的动态导入方式 代码稍显复杂,不如静态 import 直观 插件系统、按需加载模块、元编程等高级场景

最终建议

  • 对于绝大多数情况,请使用 import 语句。 这是Python设计的核心方式,也是最符合Pythonic(优雅)的写法。
  • 只有在需要将一个脚本完全独立地作为任务来执行时,才考虑 subprocess
  • 请谨慎使用 exec(),并确保你完全理解其风险。 它主要用于处理你动态生成的、可信的代码。
  • importlib 是一个强大的工具,但在日常开发中不如前三种常见,当你需要根据字符串或变量名来决定导入哪个模块时,它就派上用场了。
分享:
扫描分享到社交APP
上一篇
下一篇