杰瑞科技汇

Python如何跨文件调用函数?

核心概念:模块

在 Python 中,每一个 .py 文件都可以看作一个 模块,模块中定义的变量、函数、类都可以被其他模块导入和使用。

Python如何跨文件调用函数?-图1
(图片来源网络,侵删)

最简单直接的方法(推荐)

这是最常见、最推荐的方式,你需要确保两个文件在同一个目录下。

步骤 1:创建包含函数的文件(模块文件)

我们创建一个名为 my_functions.py 的文件,里面定义几个函数。

my_functions.py

# my_functions.py
def greet(name):
    """向指定的人问好"""
    print(f"你好, {name}! 欢迎来到 Python 世界。")
def add(a, b):
    """计算两个数的和"""
    result = a + b
    return result
# 你也可以定义一些变量
PI = 3.14159

步骤 2:创建调用函数的文件

我们创建另一个文件 main.py 来调用 my_functions.py 里的函数。

Python如何跨文件调用函数?-图2
(图片来源网络,侵删)

main.py

# main.py
# 1. 导入整个模块
import my_functions
# 2. 使用 模块名.函数名 的方式来调用
print("--- 调用 my_functions 中的函数 ---")
my_functions.greet("Alice")
# 调用另一个函数
sum_result = my_functions.add(10, 5)
print(f"10 + 5 的计算结果是: {sum_result}")
# 访问模块中的变量
print(f"圆周率 PI 的值是: {my_functions.PI}")

如何运行?

  1. my_functions.pymain.py 放在同一个文件夹里。

  2. 打开终端或命令提示符,进入这个文件夹。

  3. 运行 main.py 文件:

    python main.py

输出结果:

--- 调用 my_functions 中的函数 ---
你好, Alice! 欢迎来到 Python 世界。
10 + 5 的计算结果是: 15
圆周率 PI 的值是: 3.14159

从模块中导入特定函数

如果你只需要模块中的某一个或几个函数,而不是整个模块,可以使用 from ... import ... 语法,这样可以直接使用函数名,而不用加上模块名前缀。

main.py (修改后)

# main.py
# 只导入 greet 函数和 PI 变量
from my_functions import greet, PI
# 现在可以直接使用函数名,无需 my_functions. 前缀
print("--- 使用 from ... import 语法 ---")
greet("Bob")
print(f"PI 的值依然是: {PI}")
# 注意:add 函数没有被导入,所以这里会报错
# sum_result = add(20, 8)  # NameError: name 'add' is not defined

导入模块并为其指定别名

当模块名很长,或者你导入的模块名可能与当前文件中的变量名冲突时,可以使用 as 为模块指定一个简短的别名。

main.py (修改后)

# main.py
import my_functions as mf  # 将 my_functions 别名为 mf
# 使用别名来调用函数
print("--- 使用 as 为模块指定别名 ---")
mf.greet("Charlie")
sum_result = mf.add(100, 50)
print(f"100 + 50 的计算结果是: {sum_result}")

调用不同目录下的函数

如果你的项目变得复杂,函数文件和调用文件不在同一个目录下怎么办?这涉及到 Python 的模块搜索路径

假设你的项目结构如下:

my_project/
├── main.py
└── utils/
    └── my_functions.py

main.py 想调用 utils/my_functions.py 中的函数。

方法 A:添加路径到 sys.path

main.py

# main.py
import sys
import os
# 1. 获取当前文件所在目录的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 2. 获取 utils 文件的绝对路径
utils_dir = os.path.join(current_dir, 'utils')
# 3. 将 utils 目录添加到 sys.path 列表中
sys.path.append(utils_dir)
# 4. 现在可以直接导入 my_functions 模块了
import my_functions
my_functions.greet("来自不同目录的 Dave")

工作原理:Python 解释器在寻找模块时,会查看 sys.path 列表中的所有路径,我们将 utils 目录手动添加到了这个列表中,所以解释器就能找到 my_functions.py 了。

方法 B:使用相对导入(适用于包)

相对导入是更专业、更 Pythonic 的方式,但它要求你的项目必须被组织成一个

  1. 创建包:在 utils 目录下创建一个名为 __init__.py 的空文件,这个文件告诉 Python:“utils 不仅仅是一个文件夹,它是一个包”。

    my_project/
    ├── main.py
    └── utils/
        ├── __init__.py  # <-- 新增这个文件
        └── my_functions.py
  2. 修改调用文件main.py 需要作为一个可执行的入口点,如果你希望 main.py 能直接运行,并且也想使用相对导入,最稳妥的方法是使用 -m 标志来运行它。

    main.py

    # main.py
    # 使用相对导入语法 . 表示当前包
    # from .utils.my_functions import greet # main.py 和 utils 在同一级
    # 但更常见的结构是 main.py 在项目根目录
    # 从 utils 包导入 my_functions 模块
    from utils import my_functions
    my_functions.greet("使用相对导入的 Eve")
  3. 如何运行: 在终端中,进入 my_project父目录my_project 的上一级),然后运行:

    # -m 表示将 my_project 作为一个模块来运行
    python -m my_project.main

    注意:如果你的 main.py 就在 my_project 根目录下,utils 是它的子目录,直接 python main.py 也可以工作,因为 my_project 目录本身被 Python 解释器临时加入了搜索路径,但 -m 方式是更标准、更健壮的做法。


总结与最佳实践

方法 语法 优点 缺点 适用场景
导入整个模块 import my_module 命名空间清晰,不易冲突 调用时需要写 module.func() 大多数情况,特别是模块较大时
导入特定函数 from my_module import func 调用方便,直接写 func() 可能导致命名冲突 只需要模块中少量功能时
导入并指定别名 import my_module as mm 代码简洁,避免冲突 需要记住别名 模块名很长,或频繁使用时
添加路径 sys.path.append(...) 灵活,能处理复杂目录结构 不够优雅,可能影响其他模块 快速脚本,或项目结构不规范时
相对导入 from . import module 专业、标准,是 Python 包的一部分 需要包结构,不能用 python file.py 直接运行 构建大型、可维护的 Python 应用时

核心建议

  1. 保持简单:如果文件在同一目录,优先使用 import modulefrom module import func
  2. 组织项目:当项目变大时,使用文件夹和 __init__.py 文件来创建包,并使用相对导入。
  3. 避免污染命名空间:除非你非常确定,否则尽量使用 import module 的方式,因为它能让你清楚地知道函数来自哪里。
分享:
扫描分享到社交APP
上一篇
下一篇