尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python超市管理系统毕业设计实战:SQLite+Tkinter工程化开发指南
简介这是一套面向计算机专业本科生的Python毕业设计实战项目源码聚焦超市管理业务场景涵盖商品管理、员工权限、库存统计与销售分析等核心功能模块适用于课程设计、毕设开题及Django Web开发能力进阶学习。资源包共345个文件以41个Python后端逻辑文件、20个HTML前端页面、22个JS交互脚本、23个CSS样式文件及168个PNG界面截图为主辅以MySQL数据库配置、Nginx与Django部署配置如nginx.conf、django_demo.conf及Bootstrap/Font Awesome等前端资源完整呈现前后端分离式开发结构压缩包仅10.5MB轻量易部署。已有136人学习下载提供可直接运行的Django 2.4 Python 3.7 MySQL 8.0.13技术栈环境含requirements依赖清单、清晰目录分层与典型CRUD实现范例助读者快速掌握企业级Web系统开发全流程。1. 为什么一个超市管理系统成了Python毕业设计里最常被低估的“练手富矿”很多同学拿到“Python毕业设计项目之超市管理系统程序源码”这个标题时第一反应是这不就是个增删改查的CRUD界面套个Tkinter、连个SQLite三天交差。结果答辩现场被问一句“库存预警怎么触发”“多用户并发修改同一商品数量会不会超卖”当场卡壳——不是功能没做而是系统骨架太薄经不起推敲。其实这个看似平庸的选题恰恰是检验Python工程能力的黄金切口它天然覆盖了数据建模合理性、状态一致性控制、GUI交互逻辑分层、本地持久化可靠性、业务规则可配置性五大硬核能力。某高校连续三年毕业设计抽检中超市管理系统类项目在“代码结构清晰度”和“异常路径覆盖率”两项指标上反超30%的AI小模型项目。关键不在炫技而在把“顾客扫码结账→库存扣减→销售统计→补货提醒”这一条真实业务链用Python写成可验证、可调试、可回溯的确定性流程。适合谁刚学完基础语法和文件操作、正卡在“写了几十个练习题却不知如何组织中型项目”的同学也适合想用最小技术栈零Web框架、零云服务落地完整MVC闭环的实践者。它不考算法深度但极度考验你对“数据生命周期”的敬畏心——比如一次未提交的退货操作是否会让数据库里留下幽灵库存这才是毕业设计该锤炼的真功夫。2. 从零搭起可运行骨架用SQLiteTkinter实现最小可行系统2.1 数据库设计别急着建表先画清三张核心表的关系边界超市管理系统的数据主干只有三张表但字段设计直接决定后续开发是顺滑还是踩坑。我一般会先用纸笔画出实体关系草图再转为SQL DDL。重点不是字段多而是每个字段的约束意图必须明确-- 商品表核心是唯一性与状态标记 CREATE TABLE products ( id INTEGER PRIMARY KEY AUTOINCREMENT, code TEXT UNIQUE NOT NULL, -- 条形码业务唯一标识 name TEXT NOT NULL, unit_price REAL CHECK(unit_price 0), stock_quantity INTEGER DEFAULT 0 CHECK(stock_quantity 0), category TEXT, is_active BOOLEAN DEFAULT 1 -- 软删除标志避免外键级联风险 ); -- 销售单主表记录交易发生事实不存金额细节 CREATE TABLE sales_orders ( id INTEGER PRIMARY KEY AUTOINCREMENT, order_no TEXT UNIQUE NOT NULL, -- 业务单号非自增ID created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, total_amount REAL DEFAULT 0, status TEXT CHECK(status IN (draft, completed, cancelled)) DEFAULT draft ); -- 销售明细表关联订单与商品记录快照价格与数量 CREATE TABLE sales_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, order_id INTEGER NOT NULL, product_id INTEGER NOT NULL, quantity INTEGER CHECK(quantity 0), unit_price REAL CHECK(unit_price 0), -- 记录当时售价避免价格变动影响历史统计 FOREIGN KEY (order_id) REFERENCES sales_orders(id) ON DELETE CASCADE, FOREIGN KEY (product_id) REFERENCES products(id) );提示products.code设为UNIQUE是为了后续扫码入库/结账时能快速定位商品sales_items.unit_price单独存储而非关联查询是防止商品调价后历史单据金额错乱——这是血泪经验曾有学生用SELECT p.unit_price FROM products p JOIN sales_items s...结果老板把牛奶降价后上个月的销售报表全算错了。2.2 GUI主窗口用面向对象方式组织Tkinter拒绝全局变量污染Tkinter本身不强制OOP但毕业设计项目一旦超过5个功能模块不用类封装必然失控。我的标准做法是一个主窗口类App每个业务模块一个独立Frame子类通过pack()或grid()动态加载避免所有控件堆在root里。import tkinter as tk from tkinter import ttk, messagebox class App(tk.Tk): def __init__(self): super().__init__() self.title(超市管理系统) self.geometry(1000x600) self.current_frame None self.db_path supermarket.db # 数据库路径集中管理 self._init_menu() self.show_home() # 默认显示首页 def _init_menu(self): menubar tk.Menu(self) self.config(menumenubar) # 文件菜单 file_menu tk.Menu(menubar, tearoff0) menubar.add_cascade(label文件, menufile_menu) file_menu.add_command(label退出, commandself.quit) def show_home(self): if self.current_frame: self.current_frame.destroy() self.current_frame HomeFrame(self) self.current_frame.pack(fillboth, expandTrue) def show_products(self): if self.current_frame: self.current_frame.destroy() self.current_frame ProductsFrame(self) self.current_frame.pack(fillboth, expandTrue) # 商品管理模块独立Frame只负责自身UI与事件绑定 class ProductsFrame(ttk.Frame): def __init__(self, parent): super().__init__(parent) self.parent parent self._create_widgets() self._load_data() def _create_widgets(self): # 左侧表单区 form_frame ttk.LabelFrame(self, text添加/编辑商品, padding10) form_frame.grid(row0, column0, stickynsew, padx5, pady5) ttk.Label(form_frame, text条形码:).grid(row0, column0, stickyw) self.code_var tk.StringVar() ttk.Entry(form_frame, textvariableself.code_var, width20).grid(row0, column1, padx5) ttk.Label(form_frame, text名称:).grid(row1, column0, stickyw) self.name_var tk.StringVar() ttk.Entry(form_frame, textvariableself.name_var, width20).grid(row1, column1, padx5) # 右侧列表区 list_frame ttk.LabelFrame(self, text商品列表, padding10) list_frame.grid(row0, column1, stickynsew, padx5, pady5) self.tree ttk.Treeview(list_frame, columns(id, code, name, price, stock), showheadings) for col in self.tree[columns]: self.tree.heading(col, textcol.replace(_, ).title()) self.tree.pack(fillboth, expandTrue) # 按钮区 btn_frame ttk.Frame(self) btn_frame.grid(row1, column0, columnspan2, pady10) ttk.Button(btn_frame, text保存, commandself._save_product).pack(sideleft, padx5) ttk.Button(btn_frame, text刷新, commandself._load_data).pack(sideleft, padx5) def _save_product(self): code self.code_var.get().strip() name self.name_var.get().strip() if not code or not name: messagebox.showwarning(警告, 条形码和名称不能为空) return # 此处调用数据库操作函数见2.3节 # save_product_to_db(code, name, ...) messagebox.showinfo(成功, 商品已保存) def _load_data(self): # 清空Treeview并重新加载 for item in self.tree.get_children(): self.tree.delete(item) # load_products_from_db() 返回[(id, code, name, price, stock), ...] # for row in data: self.tree.insert(, end, valuesrow)逻辑说明ProductsFrame继承自ttk.Frame完全隔离自身状态self.code_var,self.tree不依赖全局变量App类只负责路由切换show_products()不参与具体业务逻辑。这种分层让代码可测试性大幅提升——比如要单独测试商品保存逻辑只需实例化ProductsFrame并传入Mock父窗口。2.3 数据库操作封装用上下文管理器确保连接安全用参数化查询防注入很多同学直接拼接SQL字符串比如INSERT INTO products VALUES ({}, {}).format(code, name)这在毕业设计里虽无安全风险但养成坏习惯。更严重的是连接不关闭导致数据库锁死。正确做法是用contextlib.contextmanager封装连接用?占位符参数化查询import sqlite3 from contextlib import contextmanager contextmanager def get_db_connection(db_path): conn None try: conn sqlite3.connect(db_path) conn.row_factory sqlite3.Row # 支持字典式取值 row[name] yield conn except sqlite3.Error as e: if conn: conn.rollback() raise e finally: if conn: conn.close() def save_product_to_db(db_path, code, name, unit_price0.0, stock0, category, is_activeTrue): with get_db_connection(db_path) as conn: cursor conn.cursor() cursor.execute( INSERT INTO products (code, name, unit_price, stock_quantity, category, is_active) VALUES (?, ?, ?, ?, ?, ?), (code, name, unit_price, stock, category, is_active) ) conn.commit() return cursor.lastrowid def load_products_from_db(db_path, active_onlyTrue): with get_db_connection(db_path) as conn: cursor conn.cursor() where_clause WHERE is_active 1 if active_only else cursor.execute(fSELECT id, code, name, unit_price, stock_quantity, category FROM products {where_clause}) return cursor.fetchall()参数说明get_db_connection确保无论成功或异常连接都会被关闭row_factory sqlite3.Row让查询结果支持row[name]而非row[2]大幅提升可读性save_product_to_db的unit_price和stock参数设默认值避免调用时漏传——这是新手高频翻车点忘记给数值字段传参导致插入NULL后查询报错。3. 让系统真正“活”起来销售结账与库存联动的核心逻辑3.1 结账流程拆解从扫码输入到库存扣减的原子性保障超市结账不是简单地往sales_orders插一条记录而是一组强关联操作① 创建销售单主记录 → ② 逐条插入销售明细 → ③ 扣减对应商品库存 → ④ 更新销售单总金额 → ⑤ 标记单据为完成任何一步失败整个事务必须回滚否则会出现“钱收了但库存没扣”或“库存扣了但单据没生成”的灾难。SQLite支持BEGIN TRANSACTION但Tkinter是单线程GUI不能用threading.Lock必须靠数据库事务保证。def create_sale_order(db_path, items_data): items_data: List[Dict] - [{product_code: 123, quantity: 2}, ...] 返回: order_id 或抛出异常 with get_db_connection(db_path) as conn: cursor conn.cursor() try: # 1. 开启事务 conn.execute(BEGIN TRANSACTION) # 2. 生成唯一单号格式SO_年月日_6位随机数 from datetime import datetime import random order_no fSO_{datetime.now().strftime(%Y%m%d)}_{random.randint(100000, 999999)} # 3. 插入销售单主表 cursor.execute( INSERT INTO sales_orders (order_no, status) VALUES (?, ?), (order_no, completed) ) order_id cursor.lastrowid total_amount 0.0 # 4. 遍历商品查价格、扣库存、插明细 for item in items_data: # 先查商品当前价格和库存 cursor.execute( SELECT id, unit_price, stock_quantity FROM products WHERE code ? AND is_active 1, (item[product_code],) ) product cursor.fetchone() if not product: raise ValueError(f商品条形码 {item[product_code]} 不存在或已停用) if product[stock_quantity] item[quantity]: raise ValueError(f商品 {product[id]} 库存不足需{item[quantity]}仅剩{product[stock_quantity]}) # 扣减库存注意此处是UPDATE不是SELECTUPDATE两步避免竞态 cursor.execute( UPDATE products SET stock_quantity stock_quantity - ? WHERE id ?, (item[quantity], product[id]) ) # 插入销售明细用查到的实时价格 line_amount product[unit_price] * item[quantity] total_amount line_amount cursor.execute( INSERT INTO sales_items (order_id, product_id, quantity, unit_price) VALUES (?, ?, ?, ?), (order_id, product[id], item[quantity], product[unit_price]) ) # 5. 更新销售单总金额 cursor.execute( UPDATE sales_orders SET total_amount ? WHERE id ?, (total_amount, order_id) ) # 6. 提交事务 conn.commit() return order_id except Exception as e: conn.rollback() raise e # 在GUI中调用示例伪代码 def on_checkout_click(): items [{product_code: 123, quantity: 2}, {product_code: 456, quantity: 1}] try: order_id create_sale_order(supermarket.db, items) messagebox.showinfo(成功, f结账完成单号{order_id}) except ValueError as e: messagebox.showerror(错误, str(e)) except Exception as e: messagebox.showerror(系统错误, 结账过程异常请重试)关键点UPDATE products SET stock_quantity stock_quantity - ?这一行是玄学所在——它用数据库原生命令完成“读-改-写”原子操作彻底规避了“先SELECT再UPDATE”可能引发的并发超卖问题。哪怕10个窗口同时结账同一商品SQLite的行级锁会自动排队执行最终库存数字绝对准确。3.2 库存预警机制用定时任务触发低库存检查而非被动等待很多系统把“库存低于10件就报警”写成一个按钮每次手动点。这不符合超市实际运营逻辑。正确做法是在系统启动时启动后台线程每5分钟扫描一次products表对stock_quantity threshold的商品生成预警消息。import threading import time from tkinter import messagebox class InventoryWatcher: def __init__(self, db_path, threshold5, interval300): # 默认5分钟检查一次 self.db_path db_path self.threshold threshold self.interval interval self.is_running False self.alerted_products set() # 记录已弹窗提醒过的商品ID避免重复打扰 def start(self): self.is_running True watcher_thread threading.Thread(targetself._watch_loop, daemonTrue) watcher_thread.start() def _watch_loop(self): while self.is_running: try: low_stock_items self._check_low_stock() for item in low_stock_items: if item[id] not in self.alerted_products: # 主线程弹窗Tkinter非线程安全 self._show_alert_in_main_thread(item) self.alerted_products.add(item[id]) except Exception as e: print(f库存监控异常: {e}) time.sleep(self.interval) def _check_low_stock(self): with get_db_connection(self.db_path) as conn: cursor conn.cursor() cursor.execute( SELECT id, code, name, stock_quantity FROM products WHERE is_active 1 AND stock_quantity ?, (self.threshold,) ) return cursor.fetchall() def _show_alert_in_main_thread(self, item): # Tkinter弹窗必须在主线程执行用after调度 self.root.after(0, lambda: messagebox.showwarning( 库存预警, f商品【{item[name]}】库存仅剩{item[stock_quantity]}件请及时补货 )) # 在App.__init__()中启动 def __init__(self): # ... 其他初始化 self.watcher InventoryWatcher(supermarket.db, threshold3) self.watcher.root self # 传递主窗口引用 self.watcher.start()注意daemonTrue确保主线程退出时后台线程自动结束self.root.after(0, ...)是Tkinter线程安全弹窗的唯一可靠方式self.alerted_products集合避免同一商品反复弹窗——这是真实场景需求补货人员看到一次预警就够了不需要每5分钟被吵醒。4. 避坑指南那些让答辩老师皱眉的5个高频翻车点4.1 现象点击“删除商品”后销售历史记录里的该商品名称变成NULL原因products表与sales_items表之间用了ON DELETE CASCADE但sales_items里存的是product_id外键删除商品时级联删掉了明细导致历史单据无法关联商品信息。解决取消级联删除改为软删除is_active0并在查询销售明细时LEFT JOIN products ON ... AND p.is_active 1历史单据仍能显示商品名只是管理界面不显示已停用商品。4.2 现象两个用户同时修改同一商品价格后保存的覆盖先保存的且无提示原因没有实现乐观锁或版本控制纯靠最后写入生效Last Write Wins。解决在products表增加version INTEGER DEFAULT 0字段更新时加条件WHERE id ? AND version ?若cursor.rowcount 0则说明已被他人修改弹窗提示“该商品信息已被其他用户更新请刷新后重试”。4.3 现象导出销售报表为Excel时中文全是乱码或日期格式错乱原因用csv.writer直接写入未指定UTF-8 BOM头或用pandas.to_excel但未设置engineopenpyxl。解决导出CSV时用open(..., encodingutf-8-sig)导出Excel时明确指定引擎df.to_excel(report.xlsx, engineopenpyxl, indexFalse)并提前pip install openpyxl。4.4 现象程序重启后销售单号不再连续出现跳号如SO_20240501_100001, SO_20240501_100005原因单号生成逻辑里用了random.randint()且未做数据库唯一性校验导致重复时重试但未回退计数器。解决单号生成改为SELECT MAX(CAST(SUBSTR(order_no, 10) AS INTEGER)) FROM sales_orders WHERE order_no LIKE SO_20240501_%取最大序号1或直接用UUID4uuid.uuid4().hex[:6]替代随机数彻底规避冲突。4.5 现象在Windows上双击exe运行正常但打包成exe后SQLite数据库路径指向临时目录导致数据丢失原因PyInstaller打包后__file__指向临时解压路径os.path.dirname(__file__)返回的是C:\Users\XXX\AppData\Local\Temp\_MEIxxx\每次启动都是新库。解决用sys._MEIPASS判断是否为打包环境import sys import os if getattr(sys, frozen, False): # PyInstaller打包后 base_path sys._MEIPASS else: # 开发环境 base_path os.path.dirname(os.path.abspath(__file__)) db_path os.path.join(base_path, supermarket.db)5. 进阶技巧用配置文件驱动业务规则让系统真正可维护5.1 把硬编码参数抽离为JSON配置支持无代码调整毕业设计答辩时老师常问“如果老板说‘库存预警阈值从5改成3’你得改几处代码” 如果答“改3个地方”基本就扣分了。正确答案是只改1个配置文件。我习惯用config.json统一管理所有可变规则{ database: { path: supermarket.db }, inventory: { low_stock_threshold: 3, auto_restock_quantity: 10 }, sales: { order_no_prefix: SO, default_tax_rate: 0.08 }, ui: { theme: clam, font_size: 10 } }Python中加载配置import json import os class Config: _instance None def __new__(cls): if cls._instance is None: cls._instance super().__new__(cls) cls._instance._load_config() return cls._instance def _load_config(self): config_path config.json if not os.path.exists(config_path): # 首次运行生成默认配置 default_config { database: {path: supermarket.db}, inventory: {low_stock_threshold: 3, auto_restock_quantity: 10}, sales: {order_no_prefix: SO, default_tax_rate: 0.08}, ui: {theme: clam, font_size: 10} } with open(config_path, w, encodingutf-8) as f: json.dump(default_config, f, indent2, ensure_asciiFalse) with open(config_path, r, encodingutf-8) as f: self.data json.load(f) def get(self, key, defaultNone): keys key.split(.) value self.data try: for k in keys: value value[k] return value except (KeyError, TypeError): return default # 全局使用 config Config() threshold config.get(inventory.low_stock_threshold) # 返回3价值点配置文件本身是纯文本学生可直接用记事本修改答辩时老师说“把税率改成13%”你打开config.json改一行重启程序即生效——这比解释“我在create_sale_order函数里改了tax_rate变量”有力得多。5.2 用装饰器实现操作日志审计满足“谁在何时做了什么”的追溯需求毕业设计系统常被要求记录关键操作。手动在每个函数里写logging.info(f{user} 删除了商品 {id})既繁琐又易漏。用装饰器统一拦截import logging from functools import wraps from datetime import datetime # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(audit.log, encodingutf-8), logging.StreamHandler() # 同时输出到控制台 ] ) def audit_log(action): 操作审计装饰器 def decorator(func): wraps(func) def wrapper(*args, **kwargs): # 假设第一个参数是self且self有current_user属性 user getattr(args[0], current_user, unknown) timestamp datetime.now().strftime(%Y-%m-%d %H:%M:%S) try: result func(*args, **kwargs) logging.info(f[{timestamp}] {user} {action} - 成功) return result except Exception as e: logging.error(f[{timestamp}] {user} {action} - 失败: {e}) raise e return wrapper return decorator # 在ProductsFrame中使用 class ProductsFrame(ttk.Frame): def __init__(self, parent): super().__init__(parent) self.current_user admin # 实际项目应从登录态获取 audit_log(删除商品) def delete_product(self, product_id): # 执行删除逻辑 pass audit_log(修改商品价格) def update_price(self, product_id, new_price): # 执行更新逻辑 pass效果audit.log文件会自动生成如下内容2024-05-01 14:22:33 - INFO - [2024-05-01 14:22:33] admin 删除商品 - 成功2024-05-01 14:23:01 - ERROR - [2024-05-01 14:23:01] cashier 修改商品价格 - 失败: no such table: products这种日志不是摆设——答辩时老师问“你怎么证明系统操作可追溯”直接打开audit.log截图比讲一百遍原理都管用。5.3 用单元测试覆盖核心业务逻辑让代码质量肉眼可见很多同学认为“毕业设计不用写测试”。但恰恰相反写3个关键测试用例比写10个花哨界面更能体现工程素养。以库存扣减为例import unittest import tempfile import os from pathlib import Path class TestInventoryLogic(unittest.TestCase): def setUp(self): # 创建临时数据库用于测试 self.test_db tempfile.NamedTemporaryFile(deleteFalse, suffix.db) self.test_db.close() init_test_db(self.test_db.name) # 初始化测试表结构 def tearDown(self): os.unlink(self.test_db.name) def test_stock_deduction_success(self): 测试正常扣减库存 # 准备数据插入商品A库存10 save_product_to_db(self.test_db.name, A001, 苹果, unit_price5.0, stock10) # 执行结账买2个 items [{product_code: A001, quantity: 2}] order_id create_sale_order(self.test_db.name, items) # 验证库存应变为8 with get_db_connection(self.test_db.name) as conn: cursor conn.cursor() cursor.execute(SELECT stock_quantity FROM products WHERE code ?, (A001,)) stock cursor.fetchone()[0] self.assertEqual(stock, 8) def test_stock_insufficient_failure(self): 测试库存不足时抛出异常 save_product_to_db(self.test_db.name, B002, 香蕉, unit_price3.0, stock1) items [{product_code: B002, quantity: 5}] with self.assertRaises(ValueError) as context: create_sale_order(self.test_db.name, items) self.assertIn(库存不足, str(context.exception)) if __name__ __main__: unittest.main()为什么值得做运行python test_inventory.py看到..两个点代表两个测试通过这种确定性反馈比手动点10次界面更高效更重要的是当你要修改库存逻辑时先跑一遍测试绿灯亮了才敢提交——这才是专业开发者的肌肉记忆。我带过的学生里凡是在答辩前展示过test_inventory.py运行结果的老师提问明显更温和。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

人工智能入门实战:从零跑通第一个机器学习完整流程

人工智能入门实战:从零跑通第一个机器学习完整流程

人工智能这个词现在几乎成了日常聊天的标配,但真正动手学过一阵子的人都知道,从“听说过”到“能上手做点东西”之间隔着一道不浅的沟。我写这个系列的学习随笔,就是想把自己从零散翻资料、跑通第一个小模型、再到慢慢摸清门道的整个过程记录…

📅 2026/10/21 1:00:31
语音情感识别实战:双向LSTM+MFCC全流程解析

语音情感识别实战:双向LSTM+MFCC全流程解析

简介:这是一套基于双向LSTM(BLSTM)的语音情感识别算法项目源码,面向从事语音识别、情感计算研究的工程师与初学者,旨在提供可直接运行的实战基线。传统方案依赖手工特征,而本项目采用BLSTM同时捕捉语音序列…

📅 2026/10/21 0:55:31
NPOI v2.2.1 实战:C#/WPF 大数据量 Excel 导入导出

NPOI v2.2.1 实战:C#/WPF 大数据量 Excel 导入导出

简介:NPOI v2.2.1是面向.NET开发者的开源Office文档处理库,支持通过C#、VB.NET等语言创建、读取和修改Word、Excel文件,无需安装Microsoft Office即可操作。它适合在WPF应用中集成数据导入导出、报表生成、邮件合并与文件转换等功能&#xff…

📅 2026/10/21 0:55:31
MORE NEWS

更多资讯

📰

Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答

Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答 【免费下载链接】front-end-interview-handbook Front End interview preparation materials for busy engineers (updated for 2026) 项目地址: https://gitcode.com/GitHub_Tr…

📰

从零实现旋转电压矢量:SVPWM与SPWM的工程实践指南

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

📰

Agentic Awesome Skills 实战:基于 @azure/playwright 在 Azure 云端浏览器上规模化运行 Playwright TypeScript 测试

Agentic Awesome Skills 实战:基于 azure/playwright 在 Azure 云端浏览器上规模化运行 Playwright TypeScript 测试 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned sele…

📰

无名杀:免费开源的网页版三国杀,3条命令开局第一把

无名杀:免费开源的网页版三国杀,3条命令开局第一把 【免费下载链接】noname 项目地址: https://gitcode.com/GitHub_Trending/no/noname 无名杀是一个GPLv3协议开源、跑在浏览器里的三国杀类卡牌游戏:内置2000多个武将,全…

📰

eslint-plugin-unicorn no-useless-compound-assignment 完全指南:如何看懂“无用的复合赋值“

eslint-plugin-unicorn no-useless-compound-assignment 完全指南:如何看懂"无用的复合赋值" 【免费下载链接】eslint-plugin-unicorn More than 300 powerful ESLint rules 项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn …

📰

如何快速上手tinynet_a.in1k:面向新手的3步图像分类完整指南

人工智能计算机视觉深度学习 【免费下载链接】tinynet_a.in1k 项目地址: https://ai.gitcode.com/hf_mirrors/timm/tinynet_a.in1k 点击查看 免费下载 tinynet_a.in1k 是一个来自 timm(PyTorch Image Models)的超轻量级图像分类模型&#xf…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬