Python 有一个专门的机制来处理这种情况,叫做 包,一个文件夹要成为一个包,必须在其中包含一个名为 __init__.py 的文件。

下面我将从基础到高级,详细解释如何在 Python 中正确地导入文件夹(包)。
核心概念:包
-
什么是包? 包本质上就是一个包含
__init__.py文件的文件夹,它允许你将相关的模块组织在一起,形成一个命名空间,避免了模块名冲突的问题。 -
__init__.py文件的作用- 将文件夹标记为包:这是最主要的作用,当 Python 解释器看到这个文件时,它就知道这个文件夹应该被当作一个包来处理。
- 执行包的初始化代码:当你的程序第一次导入这个包时,
__init__.py文件里的代码会被执行一次。 - *控制 `from package import
的行为**:你可以在init.py中定义一个名为all的列表,来指定使用from package import *` 时应该导入哪些模块。
简单项目结构
假设你的项目结构如下,并且你希望在 main.py 中使用 my_module.py 中的函数。

my_project/
├── main.py
└── my_folder/
└── my_module.py
-
my_folder/my_module.py# my_folder/my_module.py def say_hello(): print("Hello from my_module inside my_folder!") -
main.py# main.py # 方法1: 直接导入模块 # 需要指定完整的路径:文件夹名.模块名 import my_folder.my_module # 调用模块中的函数 my_folder.my_module.say_hello() # 方法2: 使用 from ... import ... from my_folder import my_module my_module.say_hello() # 方法3: 导入模块中的特定函数 from my_folder.my_module import say_hello say_hello()
如何运行:
- 打开终端或命令提示符。
- 使用
cd命令切换到my_project目录下。 - 运行
python main.py。
输出:

Hello from my_module inside my_folder!
Hello from my_module inside my_folder!
Hello from my_module inside my_folder!
关键点:
- Python 会自动在当前目录下查找你想要导入的模块和包,这就是为什么你需要在
main.py所在的目录(my_project)运行它。 - 导入路径是相对于执行脚本的位置,而不是脚本文件本身的位置。
更复杂的包结构
当一个项目变大时,你会有多层嵌套的包,假设结构如下:
my_project/
├── main.py
└── my_package/
├── __init__.py # (1) 这个文件可以为空
├── module_a.py
├── sub_package/
│ ├── __init__.py # (2) 这个文件可以为空
│ └── module_b.py
└── utils.py
-
my_package/sub_package/module_b.py# my_package/sub_package/module_b.py def calculate_sum(a, b): return a + b -
main.py# main.py # 导入深层嵌套的模块 from my_package.sub_package import module_b print(f"Sum of 5 and 3 is: {module_b.calculate_sum(5, 3)}") # 导入另一个模块 from my_package import module_a module_a.some_function() # 假设 module_a 中有这个函数 # 导入 utils from my_package import utils utils.do_something() # 假设 utils 中有这个函数
如何运行:
和场景一完全相同,确保在 my_project 目录下运行 python main.py。
将项目安装到 Python 环境(高级用法)
如果你的项目是一个可重用的库,并且你希望在任何地方都能像导入 requests 或 numpy 一样导入它,你需要将其“安装”到你的 Python 环境中。
步骤:
-
创建
setup.py文件 在你的项目根目录(my_project)下创建一个setup.py文件。# my_project/setup.py from setuptools import setup, find_packages setup( name='my-awesome-package', # 你包的名称 version='0.1', # 版本号 description='A sample Python package', # 描述 packages=find_packages(), # 自动查找所有包(包含 __init__.py 的文件夹) ) -
安装你的包 在终端中,确保你位于
my_project目录下,然后运行:pip install .
pip install .会告诉 pip 安装当前目录下的包。pip install -e .(推荐用于开发) 会以“可编辑模式”安装,这意味着你对源代码的修改会立即生效,无需重新安装。
-
在任何地方导入 安装完成后,你可以在任何 Python 脚本中导入你的包,无论脚本在哪个目录下。
# 任何地方的 script.py import my_package from my_package.sub_package import module_b module_b.calculate_sum(10, 20)
常见问题与解决方案
问题1:ModuleNotFoundError: No module named 'my_folder'
- 原因:你在
main.py中尝试导入my_folder,但main.py不在my_folder的父目录中。 - 解决方案:
- 确保在正确的目录下运行脚本:在终端中,
cd到你的项目根目录(即包含my_folder的文件夹),然后运行python main.py。 - 修改
PYTHONPATH:如果无法改变运行目录,可以临时添加你的项目路径到PYTHONPATH环境变量。# 在 Linux/macOS export PYTHONPATH="${PYTHONPATH}:/path/to/your/my_project" # 在 Windows (Command Prompt) set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\my_project然后再运行你的 Python 脚本。
- 确保在正确的目录下运行脚本:在终端中,
问题2:ImportError: attempted relative import with no known parent package
- 原因:当你直接运行一个包内部的模块时(
python my_package/module_a.py),该模块不知道它属于一个更大的包结构,因此无法使用相对导入(如from . import module_b)。 - 解决方案:
- 永远不要直接运行包内部的模块,始终从项目根目录运行主脚本(如
main.py),并在该脚本中导入你需要的模块。 - 如果你的
main.py就在包内部(不推荐),可以使用-m标志来告诉 Python 将该文件作为模块运行:# 假设 my_project 是一个包 python -m my_project.main
- 永远不要直接运行包内部的模块,始终从项目根目录运行主脚本(如
| 场景 | 方法 | 关键点 |
|---|---|---|
| 简单导入 | import folder.module 或 from folder import module |
确保在正确的父目录下运行脚本。 |
| 复杂包结构 | import package.sub_package.module |
使用点号 来表示层级关系。 |
| 开发可重用库 | 创建 setup.py运行 pip install . |
将项目安装到 Python 环境中,使其全局可用。 |
| 避免常见错误 | ModuleNotFoundErrorImportError |
检查运行目录和导入路径,不要直接运行包内模块。 |
理解工作目录和模块搜索路径是解决 Python 导入问题的核心。
