Python通过分层设计、接口抽象、工具检测和局部导入等手段约束模块依赖方向,确保高层模块依赖低层模块,避免循环依赖并降低耦合度。

Python 本身不强制依赖方向,但可以通过设计规范和工具约束模块间的引用关系,避免循环依赖、降低耦合度。关键在于主动管理 import 语句的流向——让高层模块依赖低层模块,而非反过来。
明确分层,控制 import 方向
将代码按职责划分为清晰层级(如 core → service → api 或 models → utils → views),规定上层模块可以导入下层,下层不能反向导入上层。
- 例如:
api.py可以 importservice.py和models.py,但models.py不能 importapi.py - 用相对导入(
from .. import xxx)时需格外注意包结构,避免跨层跳转 - 在
__init__.py中谨慎暴露接口,避免隐式引入高阶模块
用接口抽象替代具体依赖
当两个模块需要协作但又不想形成强依赖时,可定义协议(Protocol)或抽象基类(ABC),让调用方依赖抽象,实现方负责具体注入。
- 比如定义
class DataFetcher(Protocol): def fetch(self) -> dict: ... -
processor.py只依赖该协议,不关心database_fetcher.py或http_fetcher.py的存在 - 运行时通过参数或配置传入具体实现,解耦编译期依赖
借助工具检测和阻断违规依赖
静态检查能提前发现不符合约定的 import 关系。
一个基于ThinkPHP5.0开发的开源PHP快速开发框架,秉承极简、极速、极致的开发理念,为开发集成了基于数据-角色的权限管理机制,集成多种灵活快速构建工具,可方便快速扩展的模块、插件、钩子、数据包,统一了模块、插件、钩子、数据包之间的版本和依赖关系,进一步降低了代码和数据的沉余,以方便开发者快速构建自己的应用。
立即学习“Python免费学习笔记(深入)”;
- 使用
pydeps生成依赖图:pydeps mypackage --max-bacon=2查看实际引用链 - 用
archunit-py(或类似规则引擎)编写策略,例如“禁止app.api导入app.tasks” - 在 CI 中集成
pylint --enable=import-error,import-self等检查项,失败即拦截
延迟导入与局部 import 控制作用域
把 import 放在函数或方法内部,可避免模块级循环引用,并限制依赖生效时机。
- 适合只在特定路径下才需要的模块(如某些 CLI 命令仅在运行时用到数据库)
- 例如:
def run_migration(): import alembic; alembic.command.upgrade(...) - 注意:不能解决根本的设计问题,仅作为补充手段,过度使用会增加维护成本









