Python 将任何以 .py 结尾的文件都视为一个模块,当你导入一个模块时,Python 会执行该模块文件中的所有顶级代码(即在函数、类或 if __name__ == "__main__": 之外的代码)。

下面我将从最简单到最复杂的情况,详细解释如何在 Python 中导入文件(模块)。
核心概念:模块、包 和 sys.path
- 模块:就是一个
.py文件。my_module.py就是一个名为my_module的模块。 - 包:是一个包含
__init__.py文件(可以是空的)的目录,它用于组织多个模块,一个名为my_package的目录,里面有module_a.py和module_b.py,my_package就是一个包。 sys.path:这是一个至关重要的列表,它告诉 Python 解释器去哪些目录下寻找模块和包,当你执行import my_module时,Python 会按顺序在sys.path中的每一个目录里查找名为my_module.py的文件。
你可以随时查看 Python 的搜索路径:
import sys print(sys.path)
sys.path 会包含:
- 当前执行的脚本所在的目录。
- 标准库的目录。
- 环境变量
PYTHONPATH中指定的目录(如果设置了)。 - 站点包目录,例如通过
pip安装的第三方库所在的位置。
导入与主脚本在同一目录下的模块
这是最常见、最简单的情况。

文件结构:
/my_project
├── main.py
└── my_module.py
my_module.py 的内容:
# my_module.py
def greet(name):
"""一个简单的问候函数"""
return f"Hello, {name}!"
PI = 3.14159
main.py 的内容:
# main.py
# 导入 my_module
import my_module
# 现在可以使用 my_module 中定义的函数和变量
message = my_module.greet("Alice")
print(message)
print(f"The value of PI is: {my_module.PI}")
如何运行:
在终端中,进入 /my_project 目录,然后运行 main.py:

cd /my_project python main.py
输出:
Hello, Alice!
The value of PI is: 3.14159
导入不同目录下的模块
当你的模块不在同一个目录下时,就需要调整 sys.path 或者使用更规范的结构。
方法 A:直接修改 sys.path (简单直接但不推荐用于生产)
如果你需要导入一个位于上级目录或同级其他目录的模块,可以临时将那个目录添加到 sys.path。
文件结构:
/my_project
├── main.py
├── src
│ └── my_module.py
└── utils
└── helper.py
main.py 的内容:
# main.py
import sys
import os
# 获取当前文件所在目录的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 获取 src 目录的绝对路径
# __file__ 是 main.py 的路径,os.path.dirname 是它的上一级目录
src_dir = os.path.join(current_dir, 'src')
# 将 src 目录添加到 sys.path 的开头
sys.path.insert(0, src_dir)
# 现在可以像导入普通模块一样导入 my_module
import my_module
print(my_module.greet("Bob"))
# 同理,导入 utils/helper.py
utils_dir = os.path.join(current_dir, 'utils')
sys.path.insert(0, utils_dir)
import helper
helper.some_helper_function()
注意:这种方法简单,但会使代码的可移植性变差,因为它硬编码了文件路径。
方法 B:将目录变为包 (推荐的最佳实践)
这是 Python 官方推荐且最健壮的方式,将需要导入的目录都变成包。
文件结构:
/my_project
├── main.py
├── src
│ ├── __init__.py # 空文件即可,表示 src 是一个包
│ └── my_module.py
└── utils
├── __init__.py # 空文件即可,表示 utils 是一个包
└── helper.py
main.py 的内容:
# main.py
# 从 src 包中导入 my_module 模块
from src import my_module
print(my_module.greet("Charlie"))
# 从 utils 包中导入 helper 模块
from utils import helper
helper.some_helper_function()
# 也可以使用点号来访问模块
import src.my_module
print(src.my_module.greet("David"))
如何运行:
在终端中,进入 /my_project 目录,然后运行 main.py:
cd /my_project python main.py
这种方式结构清晰,易于管理,是大型项目中的标准做法。
导入上级目录的模块
假设你的项目结构如下,并且你希望从 subfolder 中的 script.py 导入 my_module.py。
文件结构:
/my_project
├── my_module.py
└── subfolder
└── script.py
script.py 的内容:
# script.py
import sys
import os
# 获取当前文件所在目录的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 获取上级目录的绝对路径
parent_dir = os.path.dirname(current_dir)
# 将上级目录添加到 sys.path
sys.path.insert(0, parent_dir)
# 现在可以导入上级目录的模块了
import my_module
print(my_module.greet("Eve"))
高级技巧:使用 importlib 动态导入
你可能需要根据字符串或变量来决定导入哪个模块,这时可以使用 importlib。
文件结构:
/my_project
├── main.py
└── calculators
├── __init__.py
├── add.py
└── multiply.py
calculators/add.py:
def calculate(a, b):
return a + b
calculators/multiply.py:
def calculate(a, b):
return a * b
main.py 的内容:
# main.py
import importlib
# 假设我们从用户输入或配置文件中得到了模块名
operation = "add" # 也可以是 "multiply"
# 动态导入模块
try:
module = importlib.import_module(f"calculators.{operation}")
result = module.calculate(10, 5)
print(f"The result of {operation} is: {result}")
# 切换操作
operation = "multiply"
module = importlib.import_module(f"calculators.{operation}")
result = module.calculate(10, 5)
print(f"The result of {operation} is: {result}")
except ImportError:
print(f"Error: The module 'calculators.{operation}' not found.")
总结与最佳实践
| 场景 | 推荐方法 | 示例 |
|---|---|---|
| 同一目录 | import my_module 或 from my_module import greet |
import my_module |
| 不同目录 | 将目录变为包,然后使用 from package import module |
from src import my_module |
| 上级目录 | 临时修改 sys.path(不推荐用于库) |
sys.path.insert(0, parent_dir) |
| 动态导入 | 使用 importlib |
importlib.import_module("my_module") |
核心建议:
- 优先使用包:组织你的代码,将相关模块放在一个带有
__init__.py文件的目录中,这是最清晰、最可维护的方式。 - 避免直接修改
sys.path:除非在脚本中临时解决特定问题,否则尽量不要在生产代码中修改sys.path,这会让依赖关系变得不明确。 - 理解
from ... import ...vsimport ...:import my_module:需要用my_module.function()来调用函数。from my_module import greet:可以直接使用greet()来调用函数,但不会把my_module这个命名空间导入进来。
希望这份详细的指南能帮助你完全理解 Python 中如何导入文件!
