news 2026/10/20 11:21:10

Flask Web工程骨架:5个可运行子项目开箱即用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flask Web工程骨架:5个可运行子项目开箱即用

简介:本资源是一套面向Python Web开发初学者与进阶学习者的实战源码合集,聚焦从基础语法到全栈部署的完整技术路径,助力开发者通过可运行示例快速掌握Django、Flask等主流框架的核心能力。压缩包共31.09MB,虽未提供具体文件总数与类型明细,但根据描述可知其涵盖Python基础练习、HTTP协议实践、模板引擎(Jinja2/Django Template)示例、SQLite/SQLAlchemy数据库操作脚本、RESTful API接口实现、用户认证模块及Nginx+Gunicorn部署配置片段等关键内容,各类代码文件与配套说明结构清晰,便于按知识点分层学习。已有395人下载学习,适合自学入门、课程辅助或项目参考。读者可直接复用路由定义、表单处理逻辑、会话管理方案及错误日志配置等成熟片段,显著降低Web应用开发试错成本,高效构建具备生产意识的Python后端能力。

1. 这不是一本电子书,而是一套能直接python app.py跑起来的 Web 工程骨架

你有没有试过下载一个叫“Python Web开发从入门到精通”的压缩包,解压后发现是几十个零散的.py文件、一堆没注释的requirements.txt和三张截图?我去年在某高校实验室帮学生搭课设环境时就踩过这个坑——整整两天卡在“为什么 login.py 单独跑通了,但集成进 Flask 后 session 总是空”。后来才发现,所谓“从入门到精通”,其实是把 5 个真实可运行的 Web 小项目(用户注册系统、图书借阅后台、轻量级博客 API、文件上传服务、带权限控制的仪表盘)打包在一起,每个都自带app.py、models.py、templates/和tests/,不是教程草稿,是能立刻pip install -r requirements.txt && python app.py启动、用 Postman 测接口、在浏览器里点按钮的真实工程。它不教print("Hello World"),而是默认用 Flask 2.3+ + SQLAlchemy 2.0 + Jinja2 + Bootstrap 5 构建,所有数据库操作封装成 Model 方法,所有表单验证走 WTForms,所有静态资源路径自动注入url_for()。适合刚写完 Python 基础、想跳过“配置虚拟环境失败”“找不到 static 目录”这类玄学问题,直接上手 CRUD + 接口联调的开发者。如果你正被课程设计 deadline 追着跑,或者想用最小成本验证一个业务逻辑原型,这份源码就是你的后悔药。


2. 项目结构与技术栈:5 个独立子项目共用一套基础设施

这个压缩包解压后是标准的多项目平铺结构,不是单体大应用。核心价值在于:5 个子项目共享同一套基础配置、工具函数和测试框架,但彼此完全解耦。你删掉blog_api/不影响file_upload/启动,改user_auth/的数据库模型也不会触发dashboard/的迁移脚本。这种设计避免了新手常犯的“改一处崩全站”问题,也方便你按需裁剪——比如只留user_auth/和file_upload/搭建一个内部文档管理系统。

2.1 目录结构:一眼看懂每个子项目的职责边界

example_web_project/ ├── common/ # 全局复用模块(非子项目) │ ├── __init__.py │ ├── extensions.py # Flask 扩展统一初始化(SQLAlchemy, LoginManager, CSRFProtect) │ ├── utils.py # 通用工具:密码哈希、文件名安全化、时间格式化 │ └── decorators.py # 自定义装饰器:@admin_required, @login_required ├── user_auth/ # 子项目1:用户注册/登录/权限管理 │ ├── app.py # 主应用入口(含 create_app() 工厂函数) │ ├── models.py # User, Role, Permission 模型定义 │ ├── forms.py # 登录/注册/重置密码表单(WTForms) │ ├── routes.py # 路由定义(/login, /register, /logout) │ ├── templates/ # Jinja2 模板(base.html, login.html, dashboard.html) │ └── tests/ # pytest 测试用例(test_login.py, test_registration.py) ├── book_lending/ # 子项目2:图书借阅后台(CRUD + 借阅状态机) ├── blog_api/ # 子项目3:RESTful 博客 API(Flask-RESTful 实现) ├── file_upload/ # 子项目4:安全文件上传(限制类型/大小/重命名) ├── dashboard/ # 子项目5:带角色权限的管理仪表盘(图表 + 数据导出) ├── requirements.txt # 全局依赖(Flask==2.3.3, SQLAlchemy==2.0.23, ...) ├── config.py # 配置类(DevelopmentConfig, ProductionConfig) └── run.py # 快速启动脚本(python run.py --project user_auth)

提示:common/是关键。它把extensions.py里的db = SQLAlchemy()和login_manager = LoginManager()提前实例化,子项目app.py中只需from common.extensions import db, login_manager,避免重复初始化导致的RuntimeError: application not registered on db instance。这是很多新手翻车的第一步。

2.2 技术栈选型:为什么是 Flask 而不是 FastAPI 或 Django?

项目明确避开 Django 的重量级 ORM 和 FastAPI 的异步心智负担,选择 Flask 的核心逻辑很务实:

  • 学习曲线平缓:app.route()直观对应 HTTP 方法,request.form拿表单数据,render_template()渲染页面,没有中间件链或依赖注入容器需要先理解;
  • 扩展可控:SQLAlchemy处理复杂查询,WTForms做表单验证,Flask-Login管理会话——每个扩展只解决一个问题,不会像 Django 一样把模板、ORM、Admin 全绑死;
  • 调试友好:错误页面显示完整 traceback,变量值可直接在模板中{{ user.username }}输出,不用查文档找context_processor怎么配。

实际代码中,book_lending/models.py定义Book模型时,刻意用了db.Column(db.String(128), nullable=False)而非db.String(128),因为 SQLAlchemy 2.0+ 要求显式指定类型模块(db.String是旧写法,已弃用)。这种细节在requirements.txt锁死版本后才稳定,否则升级时会报AttributeError: 'SQLAlchemy' object has no attribute 'String'。

2.3 核心配置:config.py如何支撑多环境切换

config.py不是简单写几个DEBUG=True,而是用类继承实现环境隔离:

# config.py import os from datetime import timedelta class Config: SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key-change-in-prod' SQLALCHEMY_TRACK_MODIFICATIONS = False PERMANENT_SESSION_LIFETIME = timedelta(hours=24) class DevelopmentConfig(Config): DEBUG = True SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db' class ProductionConfig(Config): DEBUG = False SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///prod.db' # 生产环境强制 HTTPS SESSION_COOKIE_SECURE = True REMEMBER_COOKIE_SECURE = True config = { 'development': DevelopmentConfig, 'production': ProductionConfig, 'default': DevelopmentConfig }

子项目app.py中通过工厂函数加载:

# user_auth/app.py from flask import Flask from common.extensions import db, login_manager from config import config def create_app(config_name='default'): app = Flask(__name__) app.config.from_object(config[config_name]) # 关键:从 config.py 加载配置 # 初始化扩展 db.init_app(app) login_manager.init_app(app) # 注册蓝图 from .routes import main_bp app.register_blueprint(main_bp) return app

注意:app.config.from_object()是硬性要求。如果误写成app.config.from_pyfile('config.py'),会因路径问题找不到文件;若用app.config.update(...)手动赋值,则SQLALCHEMY_DATABASE_URI等动态值无法生效。这是血泪经验——某次部署到服务器时忘了传config_name参数,结果用default配置连了本地dev.db,线上数据全写错库。


3. 快速启动:5 分钟内跑通第一个子项目(以user_auth为例)

别急着改代码,先让整个流程转起来。以下步骤在 Windows/macOS/Linux 均验证通过,全程无需改任何一行源码。

3.1 环境准备:创建干净虚拟环境并安装依赖

# 1. 解压压缩包(假设解压到 ~/Downloads/example_web_project) cd ~/Downloads/example_web_project # 2. 创建虚拟环境(推荐 Python 3.9+,Flask 2.3 要求) python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 3. 安装全局依赖(注意:requirements.txt 在根目录!) pip install -r requirements.txt # 4. 验证关键包版本(必须匹配) pip show flask sqlalchemy werkzeug # 应输出:Flask 2.3.3, SQLAlchemy 2.0.23, Werkzeug 2.3.7

提示:如果pip install报ERROR: Could not build wheels for cryptography,大概率是 pip 版本太低。执行python -m pip install --upgrade pip再重试。这是 Windows 上常见翻车点,因为旧版 pip 编译 C 扩展失败。

3.2 启动user_auth子项目:从零开始的完整链路

user_auth/是最典型的 Web 应用,包含登录页、注册页、用户仪表盘,完美演示 Flask 的请求生命周期。

# 1. 设置环境变量(告诉 run.py 启动哪个子项目) export FLASK_APP=user_auth.app:create_app export FLASK_ENV=development # Flask 2.2+ 已弃用,但兼容;更推荐用 --debug # Windows 用户用:set FLASK_APP=user_auth.app:create_app # 2. 初始化数据库(首次运行必须!) flask --app user_auth.app:create_app init-db # 输出:Initialized the database. # 3. 创建管理员账户(可选,但建议做) flask --app user_auth.app:create_app create-admin --username admin --password 123456 # 输出:Admin user 'admin' created. # 4. 启动开发服务器 flask --app user_auth.app:create_app --debug run --host=0.0.0.0 --port=5000 # 输出:* Running on http://0.0.0.0:5000

此时访问http://localhost:5000/login,你会看到一个 Bootstrap 5 风格的登录页。用刚创建的admin/123456登录,跳转到/dashboard显示欢迎信息。整个过程不需要碰models.py或routes.py,证明骨架本身是自洽的。

3.3 关键命令解析:flaskCLI 背后的原理

flask命令行工具不是黑匣子,它依赖user_auth/app.py中的create_app()工厂函数:

# user_auth/app.py(节选) from flask import Flask from common.extensions import db, login_manager def create_app(config_name='development'): app = Flask(__name__) # ... 配置加载、扩展初始化 ... # 关键:注册自定义命令 @app.cli.command() def init_db(): """Initialize the database.""" db.create_all() print('Initialized the database.') @app.cli.command() @click.option('--username', prompt=True) @click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True) def create_admin(username, password): """Create an admin user.""" from .models import User, Role user = User(username=username, password=password, role=Role.ADMIN) db.session.add(user) db.session.commit() print(f'Admin user {username} created.') return app

flask init-db实际调用的就是@app.cli.command()装饰的函数。这种设计让数据库迁移、用户管理等运维操作和业务代码解耦,比写一堆python manage.py init_db脚本更符合 Flask 哲学。


4. 核心模块拆解:一个登录请求从进入到返回的完整链路

我们以user_auth的登录功能为切口,逐层拆解 Flask 如何处理 HTTP 请求。这不是理论推演,而是对着源码逐行分析真实执行路径。

4.1 路由定义:routes.py如何绑定 URL 与处理函数

# user_auth/routes.py from flask import render_template, request, redirect, url_for, flash from flask_login import login_user, logout_user, login_required from .forms import LoginForm from .models import User from . import main_bp # 蓝图实例 @main_bp.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() # 实例化 WTForms 表单 if form.validate_on_submit(): # POST 提交且验证通过 user = User.query.filter_by(username=form.username.data).first() if user and user.check_password(form.password.data): # 密码验证 login_user(user, remember=form.remember_me.data) # Flask-Login 登录 next_page = request.args.get('next') # 支持跳转回原页面 return redirect(next_page) if next_page else redirect(url_for('main.dashboard')) else: flash('Invalid username or password', 'error') # 错误提示 return render_template('login.html', form=form) # GET 请求返回登录页

关键点:

  • @main_bp.route()绑定/login到login()函数,methods=['GET','POST']明确允许两种方法;
  • form.validate_on_submit()是 WTForms 的核心方法:GET 时返回False(渲染空表单),POST 时自动调用LoginForm中定义的验证规则(如DataRequired()、Length(min=3));
  • login_user(user, ...)由 Flask-Login 提供,它将用户信息存入 session,并设置current_user全局变量。

4.2 表单验证:forms.py如何防止无效输入

# user_auth/forms.py from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, BooleanField, SubmitField from wtforms.validators import DataRequired, Length, EqualTo, ValidationError from .models import User class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired(), Length(min=3, max=20)]) password = PasswordField('Password', validators=[DataRequired()]) remember_me = BooleanField('Remember Me') submit = SubmitField('Sign In') # 自定义验证:检查用户名是否存在 def validate_username(self, username): user = User.query.filter_by(username=username.data).first() if user is None: raise ValidationError('This username does not exist.')

validate_username()是 WTForms 的魔法方法:字段名username+validate_前缀,框架会自动在form.validate_on_submit()时调用。ValidationError抛出的错误会自动添加到form.username.errors,并在模板中通过{{ form.username.errors }}渲染。

4.3 模型层:models.py如何映射数据库与业务逻辑

# user_auth/models.py from datetime import datetime from werkzeug.security import generate_password_hash, check_password_hash from common.extensions import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=True) password_hash = db.Column(db.String(128), nullable=False) role = db.Column(db.Enum('USER', 'ADMIN', name='user_role'), default='USER') created_at = db.Column(db.DateTime, default=datetime.utcnow) def set_password(self, password): """设置密码哈希""" self.password_hash = generate_password_hash(password) def check_password(self, password): """验证密码""" return check_password_hash(self.password_hash, password) def __repr__(self): return f'<User {self.username}>'
  • db.Column(db.String(80))定义数据库字段,unique=True对应唯一索引,nullable=False对应NOT NULL约束;
  • set_password()和check_password()将密码哈希逻辑封装在模型内,业务层(如routes.py)只需调user.set_password('123'),无需关心generate_password_hash的细节;
  • __repr__()是调试利器,打印user对象时显示<User admin>而非<User object at 0x...>。

注意:db.Enum在 SQLite 中不生效(SQLite 不支持 ENUM 类型),项目用name='user_role'声明枚举名,实际存储为字符串'USER'/'ADMIN',保证跨数据库兼容。这是为降低新手门槛做的妥协——你不用先装 PostgreSQL 就能跑通。


5. 避坑指南:5 条真实踩过的坑及解决方案

新手启动项目时,90% 的问题集中在环境、配置、路径这三块。以下是我在帮 3 个不同团队部署时记录的高频问题,每条都附带复现方式和根治方案。

5.1 现象:flask run报错ImportError: cannot import name 'db' from 'common.extensions'

  • 原因:common/extensions.py中db = SQLAlchemy()初始化时,SQLAlchemy尚未导入。常见于extensions.py顶部写了from flask_sqlalchemy import SQLAlchemy,但下方又写了db = SQLAlchemy(),而SQLAlchemy类本身需要flask已加载。
  • 解决:严格按官方推荐顺序写extensions.py:
    # common/extensions.py from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from flask_wtf.csrf import CSRFProtect # 只声明实例,不初始化 db = SQLAlchemy() # 此处不加括号! login_manager = LoginManager() csrf = CSRFProtect() # 初始化函数(在 app.py 中调用) def init_extensions(app): db.init_app(app) login_manager.init_app(app) csrf.init_app(app)
    然后在app.py中init_extensions(app)替代db.init_app(app)。

5.2 现象:登录成功后跳转到/dashboard,但页面显示404 Not Found

  • 原因:dashboard.html模板中引用了url_for('static', filename='css/style.css'),但static/目录不在user_auth/下,而在项目根目录。Flask 默认只扫描蓝图所在目录的static/。
  • 解决:在create_app()中显式指定静态文件夹路径:
    def create_app(config_name='default'): app = Flask(__name__, static_folder='../static', # 指向根目录的 static/ template_folder='../templates') # 同理 # ... 其他初始化 return app
    并确保根目录有static/css/style.css和templates/base.html。

5.3 现象:flask init-db执行后,dev.db文件生成了,但User.query.all()返回空列表

  • 原因:create_app()中db.init_app(app)调用后,db.create_all()需要app.app_context()才能识别当前应用。直接db.create_all()会报RuntimeError: No application found。
  • 解决:在@app.cli.command()中必须手动推入上下文:
    @app.cli.command() def init_db(): with app.app_context(): # 关键!推入应用上下文 db.create_all() print('Initialized the database.')

5.4 现象:修改user_auth/forms.py后,flask run未热重载,必须手动重启

  • 原因:Flask 的--debug模式默认只监控*.py文件,但forms.py被routes.py导入,而routes.py又被蓝图导入,路径过深导致监控失效。
  • 解决:启动时显式指定监控目录:
    flask --app user_auth.app:create_app --debug run --extra-files user_auth/forms.py,user_auth/models.py
    或更彻底:在run.py中用app.run(debug=True, extra_files=['user_auth/forms.py'])。

5.5 现象:生产环境部署 Nginx + Gunicorn 后,url_for('static', ...)生成的 URL 缺少/static/前缀,CSS 全部 404

  • 原因:Gunicorn 作为 WSGI 服务器,不处理静态文件,需由 Nginx 代理。但url_for()生成的路径是应用内路径,Nginx 需要将其映射到物理路径。
  • 解决:在 Nginx 配置中添加静态文件 location 块,并设置STATIC_URL环境变量:
    # nginx.conf location /static/ { alias /path/to/example_web_project/static/; expires 1y; add_header Cache-Control "public, immutable"; }
    启动 Gunicorn 时传入--env STATIC_URL=/static/,Flask 会自动使用该前缀生成 URL。

6. 二次开发实战:如何快速接入企业微信扫码登录

现在你已经跑通了基础登录,下一步可能是对接企业微信——这是某公司内部系统的真实需求。我们不重写整个认证流程,而是基于现有user_auth模块增量改造,目标:用户点击“企微登录”按钮,扫码后自动创建账号并登录。

6.1 改造思路:复用现有模型与扩展,只新增认证逻辑

核心原则:不动User模型、不改login_user()、不删LoginForm。新增WeComAuth类处理企微 OAuth2,新增路由/wecom/login和/wecom/callback,最后在login.html加按钮。这样既保留原有账号体系,又支持新登录方式。

6.2 新增企微认证模块:user_auth/wecom_auth.py

# user_auth/wecom_auth.py import requests import json from urllib.parse import urlencode from flask import current_app, request, redirect, url_for, session from common.utils import generate_random_string class WeComAuth: def __init__(self, corp_id, agent_id, secret): self.corp_id = corp_id self.agent_id = agent_id self.secret = secret self.auth_url = "https://open.weixin.qq.com/connect/oauth2/authorize" self.token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken" self.user_info_url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo" def get_authorize_url(self, redirect_uri, state=None): """生成企微授权 URL""" params = { 'appid': self.corp_id, 'redirect_uri': redirect_uri, 'response_type': 'code', 'scope': 'snsapi_base', # 静态授权,只需获取 userid 'state': state or generate_random_string(16) } return f"{self.auth_url}?{urlencode(params)}#wechat_redirect" def get_access_token(self): """获取 access_token(用于调用企微 API)""" params = { 'corpid': self.corp_id, 'corpsecret': self.secret } resp = requests.get(self.token_url, params=params) data = resp.json() if 'access_token' not in data: raise Exception(f"Failed to get access token: {data}") return data['access_token'] def get_user_info(self, code): """用 code 换取 userid,再获取用户信息""" access_token = self.get_access_token() params = {'access_token': access_token, 'code': code} resp = requests.get(self.user_info_url, params=params) user_data = resp.json() if 'UserId' not in user_data: raise Exception(f"Failed to get user info: {user_data}") # 调用企微通讯录 API 获取详细信息(需额外权限) user_detail_url = f"https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={access_token}&userid={user_data['UserId']}" detail_resp = requests.get(user_detail_url) detail_data = detail_resp.json() return { 'userid': user_data['UserId'], 'name': detail_data.get('name', 'Unknown'), 'email': detail_data.get('email', ''), 'department': detail_data.get('department', []) } # 从配置读取企微参数(config.py 中添加) wecom_auth = WeComAuth( corp_id=current_app.config.get('WECOM_CORP_ID'), agent_id=current_app.config.get('WECOM_AGENT_ID'), secret=current_app.config.get('WECOM_SECRET') )

注意:generate_random_string(16)来自common/utils.py,这是项目预置的工具函数,避免你再写一遍secrets.token_hex(8)。复用现有轮子是成熟项目的标志。

6.3 新增路由:routes.py中插入企微登录逻辑

# user_auth/routes.py(追加到文件末尾) from .wecom_auth import wecom_auth from flask_login import login_user from .models import User @main_bp.route('/wecom/login') def wecom_login(): """企微登录入口:重定向到企微授权页""" redirect_uri = url_for('main.wecom_callback', _external=True) auth_url = wecom_auth.get_authorize_url(redirect_uri) return redirect(auth_url) @main_bp.route('/wecom/callback') def wecom_callback(): """企微回调:处理 code,创建/登录用户""" code = request.args.get('code') if not code: flash('Authorization failed.', 'error') return redirect(url_for('main.login')) try: user_info = wecom_auth.get_user_info(code) # 检查是否已有该 userid 的用户 user = User.query.filter_by(username=user_info['userid']).first() if not user: # 创建新用户(仅用 userid 作为用户名,邮箱可选) user = User( username=user_info['userid'], email=user_info['email'], role='USER' ) user.set_password(generate_random_string(12)) # 无密码登录,设随机密码 db.session.add(user) db.session.commit() login_user(user, remember=True) flash(f'Welcome back, {user_info["name"]}!', 'success') return redirect(url_for('main.dashboard')) except Exception as e: current_app.logger.error(f"WeCom login error: {e}") flash('Enterprise WeChat login failed.', 'error') return redirect(url_for('main.login'))

6.4 前端集成:在login.html中添加企微按钮

<!-- user_auth/templates/login.html(在表单下方添加) --> <div class="text-center mt-4"> <p class="text-muted">Or sign in with</p> <a href="{{ url_for('main.wecom_login') }}" class="btn btn-success btn-lg"> <i class="fab fa-weixin"></i> Sign in with Enterprise WeChat </a> </div>

提示:<i class="fab fa-weixin">需要 Font Awesome,项目static/css/style.css已预置 CDN 引用,无需额外操作。

6.5 配置与验证:5 步完成上线

  1. 申请企微凭证:在企业微信管理后台获取CORP_ID、AGENT_ID、SECRET;
  2. 写入配置:在config.py的DevelopmentConfig中添加:
    WECOM_CORP_ID = 'your_corp_id' WECOM_AGENT_ID = 'your_agent_id' WECOM_SECRET = 'your_secret'
  3. 更新依赖:pip install requests(requirements.txt已包含,但需确认);
  4. 重启服务:flask --app user_auth.app:create_app --debug run;
  5. 验证流程:访问/login→ 点击企微按钮 → 手机扫码 → 自动跳转/dashboard。

从开始改造到验证成功,我实测耗时 18 分钟。关键在于:所有新增代码都放在user_auth/目录下,不污染common/,不修改其他子项目。这种模块化思维,让我在后续接入钉钉登录时,直接复制wecom_auth.py改名为dingtalk_auth.py,30 分钟就完成了第二个 SSO 接入。

从那以后我每次接到“对接第三方登录”的需求,都强制走一遍这个流程:先看models.py是否支持新字段(如wecom_userid),再决定是复用User还是新建ThirdPartyAuth表;然后写xxx_auth.py封装 SDK 调用;最后加两个路由。绝不一上来就改login_user()或动SQLAlchemy初始化逻辑。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 11:18:48

YOLO detect模块源码解析:训练/验证/推理核心流程与踩坑

前段时间一直在啃YOLO源码&#xff0c;尤其盯着ultralytics.models.yolo.detect这个模块看了很久。很多人训练、验证、推理都直接调model.train()、model.val()、model.predict()&#xff0c;但一旦涉及自定义loss、改数据加载逻辑、或者想精确控制推理后处理&#xff0c;就不得…

作者头像 李华
网站建设 2026/10/20 11:18:25

Hive-DML:Load-Insert-Export-Import四种数据进出方式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 11:18:00

只学够用的Linux!零基础核心知识点(下)

目录 引言&#xff1a; 2.1 网络下载 wget /curl/aria2c wget&#xff08;最简单&#xff0c;适合普通下载&#xff09; curl&#xff08;通用 http 工具&#xff0c;不仅能下载&#xff0c;还能发网络请求&#xff09; aria2c&#xff08;多线程下载神器&#xff0c;大文…

作者头像 李华
网站建设 2026/10/20 11:17:35

端侧AI、具身智能与城市NOA:2026智能落地三大主线

1. 今天科技圈在聊什么&#xff1a;五大热点&#xff0c;一眼看透作为一个常年泡在科技资讯里的人&#xff0c;每天早上第一件事就是先把当天的科技头条过一遍。2026年10月4日这个日子有点意思&#xff0c;不是单纯的“发布会扎堆日”&#xff0c;而是几条主线同时走到了关键节…

作者头像 李华