有句话说得很心酸:写 Python 的人生,70% 在写代码,30% 在怨念“我到底应该怎么组织这些文件?”

  很多人写着写着就发现:

  • 项目越大越乱
  • 文件越多越不敢动
  • 别人一看你项目结构,眼神都写着:这兄弟怕不是把脚本玩成工程了?
  • 自己半年后回头看项目:我是谁?我在哪?我写的这是啥?

      但你别笑——这种事真不是你一个人遇到。因为“怎么规划项目结构”,从入门到十年老兵,都有人被它折磨过。

      写 Python 项目为什么越写越乱?5 种结构讲清楚,你会突然开窍!

      今天我们就把这个最“玄学”的东西,说清楚、讲明白、落到地上。不是给你列 5 种结构,而是告诉你在真实世界里,它们什么时候能救你命。

      更重要的,我会用最白话的方式讲清楚——你为什么非得学会它们,否则代码只会写得越来越痛苦。

      放心,文风不高冷、不端着,就是讲人话。代码示例我全部保留了,不做修改。

      准备好了?开始。

    当你写 Python,只靠一个文件撑天下时…

      每个学 Python 的人,都经历过一个阶段:所有逻辑都塞进一个 .py 文件里。为什么?因为简单,爽,敲起来干净利落。

      于是你得到一个项目:

      calculator.pyrequirements.txtREADME.md

      一个文件统治世界。

      看起来像这样:

      # calculator.py"""简易计算器应用"""def add(a, b): """加法运算""" return a + bdef subtract(a, b): """减法运算""" return a - bdef main(): print("简易计算器") num1 = float(input("输入第一个数字: ")) num2 = float(input("输入第二个数字: ")) result = add(num1, num2) print(f"{num1} + {num2} = {result}")if __name__ == "__main__": main()

      像不像你刚学 Python 时的感觉?

      这类项目结构很温柔、很体贴,优点简单粗暴:

  • 不用考虑文件在哪里
  • 不用想模块怎么放
  • 不用担心导入路径
  • 想写哪就写哪,天大地大一个文件最大

      只要你的项目不超过 200 行代码,这玩意儿真的香到爆。

      但只要突破 200 行,一切都变味了:

  • 你开始找不到函数
  • 查 bug 像在迷宫探险
  • 想改一个逻辑影响整片项目
  • 文件越滚越大,像吃了炫迈一样停不下来

      这个时候你就会意识到一个真相:

      单文件就是单身:开始简单,后面全靠硬扛。

      于是你开始考虑第二种结构。

    当代码开始长胖:模块化出场救火

      项目稍微上点规模后,人就会有一种本能——“代码太挤了,我想给它们分房间。”

      于是第二阶段来了:按功能拆成多个文件,每个文件负责一件事。

      于是你得到一套清爽的目录:

      data_processor/├── main.py├── data_loader.py├── data_cleaner.py├── analyzer.py├── config.py├── requirements.txt└── README.md

      好处显而易见:

  • 数据加载归一个文件
  • 数据清洗归另一个文件
  • 逻辑分析归另一个文件
  • main.py 只负责流程,不像工厂流水线全塞一起

      专业点叫“模块化”,俗话讲就是“分房睡”。

      对应代码示例如下(保持不变):

      # data_loader.pydef load_csv(filepath): """加载CSV文件""" import pandas as pd return pd.read_csv(filepath)# data_cleaner.py def remove_duplicates(df): """去除重复数据""" return df.drop_duplicates()# analyzer.pydef calculate_statistics(df): """计算基本统计量""" return df.describe()# main.pyfrom data_loader import load_csvfrom data_cleaner import remove_duplicatesfrom analyzer import calculate_statisticsdef process_data(filepath): data = load_csv(filepath) clean_data = remove_duplicates(data) stats = calculate_statistics(clean_data) return stats

      这种结构的本质是:

      文件变多,但心态变轻松。

      项目稍微复杂一点的人,几乎都会走到这里。

      但人生往往比你计划得复杂得多——你以为模块化够用了,但真正大项目根本压不住。

      于是第三阶段出现。

    当项目越来越像工程:包结构登场

      从这里开始,你写的是Python 项目,不是脚本了。

      项目结构长这样:

      ml_project/├── __init__.py├── main.py├── data/│ ├── __init__.py│ ├── preprocessing.py│ └── validation.py├── models/│ ├── __init__.py│ ├── trainer.py│ └── predictor.py├── utils/│ ├── __init__.py│ └── helpers.py├── tests/│ ├── test_data.py│ └── test_models.py├── requirements.txt└── README.md

      这就是你在 GitHub 上看到的大多数 Python 工程。

      为什么要这么麻烦?因为随着项目变大,你会遇到:

  • 循环导入
  • 模块命名冲突
  • 代码可读性下降
  • 很多逻辑需要封装
  • 必须拆层级,不然维护成本爆炸

      这个时候,“包”(package)的价值就出来了。

      包结构让一件事情变得有边界:属于数据处理的代码,都去 data 目录;属于模型训练的,都去 models;全局工具函数统一放 utils。

      示例代码如下:

      # ml_project/data/preprocessing.pydef normalize_data(data): """数据标准化""" return (data - data.mean()) / data.std()# ml_project/models/trainer.pyfrom ..data.preprocessing import normalize_dataclass ModelTrainer: def __init__(self, model): self.model = model def train(self, X, y): X_normalized = normalize_data(X) self.model.fit(X_normalized, y)

      看到这句了吗?

      from ..data.preprocessing import normalize_data

      没错,包结构能让你:

  • 清楚地知道模块之间的层级关系
  • 避免乱导包
  • 通过相对 import 让跨目录调用干干净净

      到这一步,你的 Python 水平已经进阶到“工程阶段”。

      但写久了你会发现:

      有些项目,不只是代码本身复杂而是逻辑拆分就必须非常明确。

      于是第四种结构登场。

    当项目逻辑开始复杂,人类发明了 MVC

      MVC 并不是 Python 专属结构,但它解决的是所有语言都会遇到的问题:

      把数据、界面、业务逻辑分开,否则项目越写越像屎山。

      典型目录:

      task_manager/├── models/│ ├── __init__.py│ └── task.py├── views/│ ├── __init__.py│ └── cli.py├── controllers/│ ├── __init__.py│ └── task_controller.py├── utils/│ └── __init__.py└── main.py

      很多人一开始不懂 MVC,觉得很虚……直到某天你写的逻辑越来越多,终于崩溃:业务逻辑写进界面?界面逻辑写进模型?模型逻辑写进控制器?

      那不是项目,那是代码混合火锅,拉都拉不开。

      MVC 要解决的东西很朴素:

  • Model:数据
  • View:展示
  • Controller:管控

      对应代码如下:

      # models/task.pyclass Task: def __init__(self, title, description): self.title = title self.description = description self.completed = False# views/cli.pyclass TaskView: def show_tasks(self, tasks): for i, task in enumerate(tasks, 1): status = "" if task.completed else "" print(f"{i}. [{status}] {task.title}")# controllers/task_controller.pyfrom models.task import Taskfrom views.cli import TaskViewclass TaskController: def __init__(self): self.tasks = [] self.view = TaskView() def add_task(self, title, description): task = Task(title, description) self.tasks.append(task)

      你会发现:

      结构一旦清晰,复杂度就降维打击。

      但还有一个层级更复杂的场景:Web。

    当你决定写 Web:结构复杂度瞬间三级跳

      只要你踏进 Flask、Django,你就不得不接受:

      Web 项目结构从来不是你想怎么写就怎么写。

      目录:

      blog_app/├── app/│ ├── __init__.py│ ├── routes.py│ ├── models/│ │ └── post.py│ ├── templates/│ │ └── index.html│ └── static/│ ├── css/│ └── js/├── tests/├── config.py├── run.py└── requirements.txt

      Web 项目为什么复杂?

  • 模板必须有模板目录
  • 静态文件必须单独放
  • 蓝图必须注册
  • 业务逻辑必须拆模块
  • 配置必须分环境配置
  • 测试必须独立

      下面是原代码示例:

      # app/__init__.pyfrom flask import Flaskdef create_app(): app = Flask(__name__) from .routes import main app.register_blueprint(main) return app# app/routes.pyfrom flask import Blueprint, render_templatemain = Blueprint('main', __name__)@main.route('/')def index(): return render_template('index.html')# run.pyfrom app import create_appapp = create_app()if __name__ == '__main__': app.run(debug=True)

      Web 项目结构的要求就是四个字:

      “规规矩矩”。

      你不规矩,它就会反噬你。

    如果你能掌握这 5 种结构,你的 Python 能力将质变

      很多人卡在语言语法,不卡在工程能力。但你写代码写到一定程度会突然明白:

      决定开发效率的不是工具,而是结构。

      掌握项目结构,你会有 5 个质变:

    1. 写项目不再纠结摆哪里,从此不卡壳
    2. 维护成本下降,半年后回头看不会骂自己
    3. 团队协作顺畅,别人一眼就能看懂
    4. 隔离逻辑、降低耦合、提升可扩展性
    5. 写出的项目结构越像开源库,你越像高级工程师

      最终一句话:

      项目结构不是形式,而是能力。结构越清晰,代码越自由。

      如果文章对你有帮助——点赞、转发、收藏、留言,一个都不要留在心里