动手学Python:从零开始构建一个“文字冒险游戏”
动手学Python:从零开始构建一个“文字冒险游戏”
大家好,我是你的技术向导。今天,我们不聊高深的框架,也不谈复杂的算法,我们来做一点“复古”又极具趣味性的事情——用Python亲手打造一个属于自己的文字冒险游戏(Text Adventure Game)。
你是否还记得那些在早期计算机上,通过一行行文字描述和简单指令来探索未知世界的日子?这种游戏的魅力在于它能激发我们最原始的想象力。而对于我们程序员来说,构建这样一个游戏,不仅是情怀的致敬,更是一次绝佳的Python编程核心能力(数据结构、控制流、面向对象)的综合实战演练。
这篇博客的目标,不仅仅是带你“写出来”,更是要带你“写得好”。我们将从最简陋的实现开始,一步步重构,最终抵达一个结构优美、易于扩展的优雅设计。准备好了吗?让我们开始这场代码的冒险吧!🚀
📜 第一章:万物之始 —— 游戏循环与朴素实现
任何一个游戏,其本质都是一个状态机。在文字冒险游戏中,最核心的状态就是“玩家当前在哪”。游戏的核心驱动力,就是一个不断循环的过程:
- 呈现状态:告诉玩家当前在哪里,看到了什么。
- 接收输入:等待玩家输入指令。
- 更新状态:根据玩家的指令,切换到新的位置或状态。
- 循环往复:回到第1步,直到游戏结束。
这个过程,我们称之为游戏循环(Game Loop)。让我们用最简单的方式来实现它。
1.1 最朴素的思想:if-elif-else
走天下
想象一下,我们有一个非常简单的世界,只有三个房间:'大厅'
, '书房'
, '花园'
。
- 大厅可以去书房。
- 书房可以回大厅,也可以去花园。
- 花园只能回书房。
最直观的实现方式可能就是一连串的 if-elif-else
判断。
# a_simple_start.pydef play_game():"""一个非常简单的、基于if-elif-else的文字冒险游戏"""current_room = '大厅'print("游戏开始!你现在位于【大厅】。")print("这是一个宏伟的石制大厅,北边有一扇通往【书房】的门。")while True:# 1. 接收玩家输入command = input("> ").strip().lower()# 2. 根据当前房间和指令更新状态if current_room == '大厅':if command == 'go north':current_room = '书房'print("\n你走进了【书房】。")print("房间里弥漫着旧书和尘土的味道。南边可以回到【大厅】,东边则通向【花园】。")else:print("无效的指令!你只能 'go north'。")elif current_room == '书房':if command == 'go south':current_room = '大厅'print("\n你回到了【大厅】。")print("这是一个宏伟的石制大厅,北边有一扇通往【书房】的门。")elif command == 'go east':current_room = '花园'print("\n你来到了【花园】。")print("空气清新,鸟语花香。西边是返回【书房】的路。")else:print("无效的指令!你只能 'go south' 或 'go east'。")elif current_room == '花园':if command == 'go west':current_room = '书房'print("\n你回到了【书房】。")print("房间里弥漫着旧书和尘土的味道。南边可以回到【大厅】,东边则通向【花园】。")else:print("无效的指令!你只能 'go west'。")# 游戏结束条件 (可以自行添加)# if command == 'quit':# print("感谢游玩!")# break# 启动游戏
if __name__ == '__main__':play_game()
运行一下,你会发现它确实能玩!但这背后隐藏着巨大的问题:
- 代码高度耦合:游戏逻辑(
if command == ...
)和游戏数据(房间描述、出口信息)完全混在一起。 - 难以扩展:想增加一个房间?你需要在多个地方修改
if-elif
逻辑,并手动复制粘贴大量的描述文本。增加100个房间?这将是一场噩梦!😱 - 可读性差:随着逻辑复杂化,这个函数会变得无比臃肿,难以维护。
这个例子很好地为我们揭示了**“什么不该做”**。现在,让我们进入第一个重要的进化阶段。
🧱 第二章:告别混乱 —— 数据驱动的设计
优秀的程序设计,一个核心原则是**“逻辑与数据分离”**。游戏的世界观、地图、物品等是数据;而玩家如何移动、如何交互,这是逻辑。我们应该把它们分开。
2.1 用字典构建世界
Python的字典(dict
)是组织结构化数据的神器。我们可以用它来描述我们的游戏世界。每个房间本身是一个字典,包含它的描述和出口信息。整个世界则是一个更大的字典,用房间名作为键(key),房间字典作为值(value)。
看看下面的结构:
# data_driven_design.py# 游戏世界数据
world = {'大厅': {'description': '这是一个宏伟的石制大厅。','exits': {'north': '书房'}},'书房': {'description': '房间里弥漫着旧书和尘土的味道。','exits': {'south': '大厅', 'east': '花园'}},'花园': {'description': '空气清新,鸟语花香。','exits': {'west': '书房'}}
}def play_game():"""一个基于数据驱动设计的文字冒险游戏"""player_location = '大厅' # 玩家的初始位置print("游戏开始!")while True:# 1. 获取当前房间的信息current_room = world[player_location]# 2. 呈现状态print(f"\n你现在位于【{player_location}】。")print(current_room['description'])# 显示可用的出口available_exits = ", ".join(current_room['exits'].keys())print(f"你可以前往的方向: {available_exits}")# 3. 接收输入command = input("> ").strip().lower()# 4. 解析和更新状态if command.startswith('go '):direction = command.split(' ')[1]if direction in current_room['exits']:# 更新玩家位置player_location = current_room['exits'][direction]else:print("那个方向没有路!")elif command == 'quit':print("感谢游玩!")breakelse:print("无效的指令!试试 'go <direction>' 或 'quit'。")# 启动游戏
if __name__ == '__main__':play_game()
对比一下:
- 清晰的分离:
world
字典清晰地定义了整个游戏世界,完全独立于play_game
函数中的游戏逻辑。 - 易于扩展:想增加一个房间?只需在
world
字典里增加一个新的键值对即可,完全不用动游戏循环的代码!比如,想从花园加一个通往“地窖”的门:
就是这么简单!'花园': {'description': '空气清新,鸟语花香。','exits': {'west': '书房', 'down': '地窖'} }, '地窖': {'description': '这里又冷又湿,角落里有个旧箱子。','exits': {'up': '花园'} }
- 逻辑更通用:游戏循环不再关心“当前在哪个具体房间”,它只关心“根据当前房间的出口数据,移动到下一个房间”。这使得逻辑变得高度可复用。
这种数据驱动的方法已经非常强大,对于中小型文字冒险游戏来说完全足够。但如果我们想引入更复杂的概念,比如玩家的背包、房间里的物品、需要钥匙才能打开的门呢?这时候,面向对象编程(OOP)将为我们提供终极的优雅解决方案。
🚀 第三章:终极进化 —— 面向对象(OOP)的优雅
面向对象编程的核心思想是将现实世界中的事物抽象成代码中的对象(Object)。在我们的游戏中,有哪些“事物”呢?
- 房间(Room):它有名字、描述、出口。
- 玩家(Player):他有当前位置、物品清单(背包)。
- 物品(Item):它有名字、描述,也许还能被使用。
- 游戏(Game):它负责组织所有房间、玩家,并驱动整个游戏流程。
让我们用类(class
)来定义这些概念。
3.1 定义核心类
1. Room
类
Room
对象将封装一个房间的所有信息。
class Room:"""代表游戏中的一个房间"""def __init__(self, name, description):self.name = nameself.description = descriptionself.exits = {} # 出口,格式: {'direction': Room_object}self.items = [] # 房间里的物品列表def add_exit(self, direction, room):"""添加一个出口到另一个房间"""self.exits[direction] = roomdef add_item(self, item):"""在房间里放置一个物品"""self.items.append(item)def get_item(self, item_name):"""从房间里拿走一个物品"""for item in self.items:if item.name.lower() == item_name.lower():self.items.remove(item)return itemreturn None
2. Item
类
物品很简单,目前只需要名字和描述。
class Item:"""代表游戏中的一个可拾取物品"""def __init__(self, name, description):self.name = nameself.description = descriptiondef __str__(self):return f"{self.name}: {self.description}"
3. Player
类
玩家类负责追踪玩家的状态。
class Player:"""代表玩家"""def __init__(self, starting_room):self.current_room = starting_roomself.inventory = [] # 玩家的背包def move(self, direction):"""尝试向某个方向移动"""if direction in self.current_room.exits:self.current_room = self.current_room.exits[direction]return Trueelse:return Falsedef take_item(self, item_name):"""从当前房间拾取物品"""item = self.current_room.get_item(item_name)if item:self.inventory.append(item)print(f"你捡起了【{item.name}】。")else:print(f"这里没有叫做 '{item_name}' 的东西。")def show_inventory(self):"""显示玩家背包里的物品"""if not self.inventory:print("你的背包是空的。")else:print("你的背包里有:")for item in self.inventory:print(f"- {item.name}")
3.2 组织一切的 Game
类
Game
类是总指挥。它负责创建世界、初始化玩家,并包含主游戏循环和命令解析。
# oop_adventure_game.py# (这里需要粘贴上面定义的 Room, Item, Player 类的代码)
# ...class Game:"""游戏主类,负责整个游戏的流程"""def __init__(self):self.player = Noneself.create_world()def create_world(self):"""创建游戏世界、房间和物品"""# 1. 创建房间hall = Room("大厅", "这是一个宏伟的石制大厅,光线昏暗。")study = Room("书房", "房间里弥漫着旧书和尘土的味道。一张木桌上放着一把【钥匙】。")garden = Room("花园", "空气清新,鸟语花香。一扇上锁的【铁门】挡住了去路。")# 2. 创建物品key = Item("钥匙", "一把生锈的旧钥匙。")# 3. 设置房间出口hall.add_exit("north", study)study.add_exit("south", hall)study.add_exit("east", garden)garden.add_exit("west", study)# 4. 在房间里放置物品study.add_item(key)# 5. 创建玩家并设置初始位置self.player = Player(hall)def play(self):"""开始游戏主循环"""print("="*30)print(" 欢迎来到文字冒险世界! ")print("="*30)print("输入 'help' 查看可用指令。")while True:self.describe_scene()command = input("> ").strip().lower()if not command:continueif self.handle_command(command):# 如果命令是 'quit',则结束循环breakdef describe_scene(self):"""描述当前场景"""room = self.player.current_roomprint(f"\n--- {room.name} ---")print(room.description)# 显示房间里的物品if room.items:item_names = ", ".join([item.name for item in room.items])print(f"你看到这里有: {item_names}")# 显示出口exits = ", ".join(room.exits.keys())print(f"可用的出口: {exits}")def handle_command(self, command):"""解析并处理玩家的指令"""parts = command.split(' ', 1)verb = parts[0]noun = parts[1] if len(parts) > 1 else ""if verb == 'quit':print("感谢游玩!再见!")return True # 返回True表示游戏结束elif verb == 'help':self.show_help()elif verb == 'go':if self.player.move(noun):# 移动成功后不需要额外打印,describe_scene会处理passelse:print("那个方向没有路!")elif verb == 'take':if noun:self.player.take_item(noun)else:print("你要拿什么? (e.g., 'take 钥匙')")elif verb == 'inventory' or verb == 'i':self.player.show_inventory()elif verb == 'look':# 'look' 命令只是重新描述场景,循环开始时会自动做passelif verb == 'use':self.handle_use_command(noun)else:print("我不明白你的意思。输入 'help' 查看帮助。")return False # 返回False表示游戏继续def handle_use_command(self, noun):"""处理'use'指令,实现简单的谜题"""if 'key' in noun and 'door' in noun and self.player.current_room.name == "花园":# 检查玩家是否有钥匙has_key = any(item.name.lower() == '钥匙' for item in self.player.inventory)if has_key:print("你用钥匙打开了铁门,背后是一条通往胜利的道路!")print("🎉 恭喜你,通关了! 🎉")# 可以在这里添加新的出口或直接结束游戏# self.player.current_room.add_exit("east", victory_room)# For simplicity, we end the game here.# This is a bit of a hack; a better way would be a game state flag.# We'll use the return value of handle_command for quitting.# So let's just print the message and let the player quit manually.# Or, we can make the game automatically end:# return True # This doesn't work here, need to refactor.# A simple flag is better:self.game_over = True # Need to add this to __init__ and check in the loopprint("输入 'quit' 退出游戏。")else:print("你没有钥匙来开这扇门!")else:print("你不能在这里这么用。")def show_help(self):"""显示帮助信息"""print("\n--- 可用指令 ---")print("go <direction> - 移动到指定方向 (e.g., go north)")print("take <item> - 拾取物品 (e.g., take 钥匙)")print("use <item> on <target> - 使用物品 (e.g., use 钥匙 on 铁门)")print("inventory (or i)- 查看你的背包")print("look - 重新查看当前环境")print("help - 显示此帮助信息")print("quit - 退出游戏")print("--------------------")# 启动游戏
if __name__ == '__main__':game = Game()game.play()
OOP设计的巨大优势:
- 高内聚,低耦合:
Room
只管房间的事,Player
只管玩家的事。每个类都像一个独立的零件,职责分明。 - 可维护性极强:想给物品增加“重量”属性?只需要修改
Item
类和Player
类的take_item
方法,其他代码完全不受影响。 - 无限扩展可能:想增加NPC?创建一个
NPC
类。想增加战斗系统?创建Monster
类,给Player
增加attack
方法。OOP为未来的复杂性提供了完美的结构基础。
💡 第四章:锦上添花 —— 进阶技巧与拓展
我们的游戏已经有了一个坚实的骨架。现在,让我们探讨一些能让它变得更专业、更酷的进阶技巧。
4.1 从外部文件加载世界
硬编码 create_world
函数依然不够灵活。专业的游戏引擎会将游戏内容(地图、物品、剧情)与引擎代码完全分离。我们可以使用JSON或YAML文件来定义我们的世界。
示例 world.json
文件:
{"rooms": {"hall": {"name": "大厅","description": "这是一个宏伟的石制大厅,光线昏暗。"},"study": {"name": "书房","description": "房间里弥漫着旧书和尘土的味道。"},"garden": {"name": "花园","description": "空气清新,鸟语花香。一扇上锁的【铁门】挡住了去路。"}},"items": {"key": {"name": "钥匙","description": "一把生锈的旧钥匙。"}},"map": {"hall": {"exits": {"north": "study"}},"study": {"exits": {"south": "hall", "east": "garden"},"items": ["key"]},"garden": {"exits": {"west": "study"}}},"player": {"start_location": "hall"}
}
在 Game
类的 create_world
方法中,你就可以读取这个JSON文件,然后动态地创建 Room
和 Item
对象,并将它们连接起来。这使得非程序员(比如游戏设计师)也能通过修改文本文件来创造和调整游戏内容!
4.2 状态持久化:保存与加载
没人喜欢从头玩一个长游戏。我们可以用Python的 pickle
模块来轻松实现游戏状态的保存和加载。pickle
可以将几乎任何Python对象(包括我们自定义的 Game
对象)序列化成一个字节流,并存入文件。
保存游戏:
import pickledef save_game(self):try:with open("savegame.pkl", "wb") as f:pickle.dump(self, f)print("游戏已保存!")except Exception as e:print(f"保存失败: {e}")
加载游戏:
# 在游戏启动时检查
if __name__ == '__main__':try:with open("savegame.pkl", "rb") as f:game = pickle.load(f)print("游戏已从存档加载!")except FileNotFoundError:print("未找到存档,开始新游戏。")game = Game()except Exception as e:print(f"加载失败: {e}。开始新游戏。")game = Game()game.play()
你需要将 save_game
功能整合到 handle_command
中,并修改主启动逻辑。
4.3 更智能的命令解析
目前的解析器还很初级。你可以引入更复杂的解析技术,比如使用正则表达式,或者构建一个简单的语法分析器,来理解更自然的语言,如 "use the rusty key on the big iron door"
。
🌟 总结
我们从一个混乱的 if-else
脚本出发,经历了一次数据驱动的重构,最终抵达了优雅而强大的面向对象设计。这个过程,浓缩了软件工程从混沌到有序的进化之路。
你现在拥有的,不仅仅是一个简单的文字游戏,而是一个可以无限扩展的游戏框架。你可以:
- 丰富世界:添加更多的房间、物品和谜题。
- 引入角色:创建
NPC
类,让他们可以对话,甚至给你任务。 - 增加挑战:设计
Monster
类和战斗系统。 - 深化剧情:通过变量和条件判断,实现分支剧情。
编程的乐趣,就在于创造。希望这次动手实践,能让你对Python的核心概念有更深刻的理解,并点燃你用代码创造世界的激情。现在,轮到你了,去构建你心中的那个奇幻世界吧!
相关文章:
动手学Python:从零开始构建一个“文字冒险游戏”
动手学Python:从零开始构建一个“文字冒险游戏” 大家好,我是你的技术向导。今天,我们不聊高深的框架,也不谈复杂的算法,我们来做一点“复古”又极具趣味性的事情——用Python亲手打造一个属于自己的文字冒险游戏&…...
【C/C++】C++26新特性前瞻:全面解析未来编程
展望未来:C26 新特性全面解析 随着 C 标准每三年一次的迭代节奏,C26(预计于 2026 年底正式发布)正在逐步成型。相比 C20 的革命性更新和 C23 的“修补增强”,C26 继续推进现代 C 的理念——更安全、更高效、更模块化&…...
Linux系统日志与守护进程开发实战指南
Linux系统日志与守护进程开发实战指南 系统日志与守护进程 ├── 系统日志syslog │ ├── 日志路径: /var/log/syslog │ └── 核心API │ ├── openlog │ ├── syslog │ └── closelog └── 守护进程daemon└── 创建步骤├── um…...
兰洋科技上合组织论坛发表专题分享,全球液冷布局引领绿色算力未来
2025年6月17-19日,中国—上海合作组织数字技术合作发展论坛在新疆克拉玛依市举办。作为第四次上海合作组织成员国信息通信技术发展部门负责人会议的配套会议,论坛以“数字化转型助力可持续发展,数字包容促进上合共同繁荣”为主题,…...
桌面小屏幕实战课程:DesktopScreen 11 SPI 水墨屏
飞书文档https://x509p6c8to.feishu.cn/docx/doxcnlzpIgj3gosCZufBTCZxlMb SPI说明 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上占用…...
小知识点五、无刷电机闭环控制(电流)
0 前言 该部分只用于自学使用,作为笔记方便后续自查。 资料参考:http://dengfoc.com 硬件:2208云台电机MT6701磁编码器 1 电流控制理论 1.1 待解决的问题 简单回顾一下在之前的学习中,我们通过 U q U_q Uq和电角度 θ \the…...
Java 编程之备忘录模式
前言 有时候,我们真希望人生能有“CtrlZ”。在日常生活中,我们经常使用“撤销”功能,例如在写 Word、画图、写代码时一不小心操作失误,就希望能回到之前的状态。这种**“状态快照 恢复”**机制,在设计模式中就叫做&a…...
SQL SERVER存储过程
什么是存储过程 SQL 存储过程(Stored Procedure)是一个在数据库中预编译并存储的一组 SQL 语句。它们可以包含查询、插入、更新、删除等数据库操作,甚至包括控制流语句(如条件判断、循环等)。存储过程可以通过调用来执…...
Vue样式绑定与条件渲染详
一、Vue样式绑定 在Vue中,我们可以通过多种方式动态地绑定样式,让界面根据数据状态变化而自动更新样式。 1. class样式绑定 (1) 字符串写法 适用场景:样式的类名不确定,需要动态指定 <template><div><!-- 绑定…...
python基于协同过滤的动漫推荐系统
目录 技术栈介绍具体实现截图系统设计研究方法:设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理,难度适中…...
光场操控新突破!3D 光学信息处理迎来通用 PSF 工程时代--《自然》子刊:无需复杂算法,这一技术让 3D 光学成像实现 “即拍即得”念日
导语 在光学成像领域,如何突破分辨率与成像速度的瓶颈,一直是科研人员探索的焦点。近日,加州大学洛杉矶分校(UCLA)的研究团队在《Light: Science & Applications》发表论文,提出了一种通用点扩散函数&a…...
ubuntu20.04如何给appImage创建快捷方式
ubuntu20.04如何给appImage创建快捷方式 1. 确保AppImage是可执行的 chmod x /path/to/your/appimage2. 创建.desktop文件 在~/.local/share/applications/目录下创建一个新的 .desktop 文件: vi ~/.local/share/applications/your-appname.desktop添加以下内容…...
网络安全之SQL RCE漏洞
引言 堡垒机(Bastion Host),也称为跳板机或运维安全审计系统,是一种用于管理和控制对内部网络资源访问的安全设备。它的主要作用是作为运维人员访问内部服务器和网络设备的唯一入口,通过集中化的身份认证、权限管理和…...
DeepSeek网页版随机点名器
用DeepSeek帮我们生成了一个基于html5的随机点名器,效果非常棒,如果需要加入名字,请在代码中按照对应的格式添加即可。 提示词prompt 帮我生成一个随机点名的HTML5页面 生成真实一点的名字数据 点击随机按钮开始随机选择 要有闪动的效果 &…...
Elasticsearch索引字段的类型
在 Elasticsearch 中,索引字段的类型(即 Mapping 中的字段类型)对搜索和存储性能影响很大。下面是各种常用数据类型的用途及推荐使用场景总结: 1. keyword 类型(精确匹配) 适合数据: 不需要分词…...
大模型在慢性病毒性肝炎预测及诊疗方案制定中的应用研究
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 二、慢性病毒性肝炎概述 2.1 疾病定义与分类 2.2 发病机制与病理特征 2.3 流行病学现状 三、数据收集与预处理 3.1 数据来源 3.2 数据清洗 3.3 特征工程 四、大模型选择与构建 4.1 模型选择依据 4.2 模型…...
DAY 43 复习日
浙大疏锦行https://blog.csdn.net/weixin_45655710 第一步:寻找并准备图像数据集 在Kaggle等平台上,你可以找到大量用于图像分类任务的数据集,例如英特尔图像分类数据集 (Intel Image Classification) 或手写数字识别数据集 (Digit Recogni…...
SQL学习笔记3
SQL常用函数 1、字符串函数 函数调用的语法:select 函数(参数); 常用的字符串函数有: 拼接字符串,将几个字符串拼到一起:concat (s1,s2,……); select concat(你好,hello); update mytable set wherefo concat(中…...
JVM调优实战 Day 7:JVM线程分析与死锁排查
【JVM调优实战 Day 7】JVM线程分析与死锁排查 文章标签 jvm调优, 线程分析, 死锁排查, JVM监控, Java性能优化, JVM参数配置 文章简述 在Java应用的高并发场景中,线程管理与死锁问题往往是性能瓶颈的根源。本文作为“JVM调优实战”系列的第7天,深入解析…...
Android-Layout Inspector使用手册
Layout Inspector Android Layout Inspector 是 Android Studio 中用于调试应用布局的工具 启动方法: 通过下载Layout Inspector插件,在 “View - Tool Windows - Layout Inspector” 或 “Tools - Layout Inspector” 启动。 主要界面区域:…...
【51单片机5毫秒定时器】2022-6-1
缘由单片机的代码,求大家来帮帮我-编程语言-CSDN问答 #include "REG52.h" unsigned char code smgduan[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0,64}; //共阴0~F消隐减号 unsigned char Js0, miao0;//中断…...
Flutter 多平台项目开发指南
Flutter 多平台项目开发指南 本指南将帮助你从 0 到 1 创建并适配一个支持 Android / iOS / Web / Windows / macOS / Linux 的 Flutter 多平台项目。 ✅ 一、创建支持多平台的 Flutter 项目 flutter create my_multi_platform_app cd my_multi_platform_app默认会生成支持以…...
Mac电脑如何搭建基于java后端的开发的各种工具服务
1. 确认Mac的CPU架构 首先,确认您的Mac是使用Intel还是Apple Silicon(如M1芯片)架构: uname -m如果返回x86_64,表示是Intel架构。如果返回arm64,表示是Apple Silicon架构。 2.安装IDEA Download Intelli…...
深入解析前端 Meta 标签:HTML 的隐形守护者与功能大师
在构建现代网页时,我们常常关注炫目的视觉效果、复杂的交互逻辑或强大的框架,却容易忽略那些深藏于 <head> 之中、看似不起眼的 <meta> 标签。这些标签如同网页的隐形守护者,无声地承担着定义文档元数据、指导浏览器行为、优化搜…...
CRON表达式编辑器与定时任务实现技术文档
1. 前端CRON表达式编辑器组件 CronExpressionEditor.vue组件是系统中用于创建和编辑CRON表达式的核心UI组件,它提供了直观的界面来生成复杂的定时任务表达式。 1.1 组件结构与状态管理 // 核心状态变量 const second ref<string>(0); const minute ref&…...
45. 跳跃游戏 II
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…...
《解锁AudioSet:开启音频分析的无限可能》
音频新时代的 “密钥”:AudioSet 登场 在科技飞速发展的今天,音频作为信息传播与交互的关键媒介,早已渗透到现代科技的各个角落。从智能手机中的语音助手,让我们通过简单的语音指令就能查询信息、发送消息,到智能家居系…...
环境太多?不好管理怎么办?TakMll 工具帮你快速切换和管理多语言、多版本情况下的版本切换。
本篇文章主要介绍一款环境管理工具,即TakMll,通过简单的入口命令 “tkm” 即可快速的管理多种语言下、多种版本的环境切换,诸如快速切换PHP、同时存在java、mave等不同版本。 作者:任聪聪 日期:2025年6月26日 TakMll 特…...
spring-ai 1.0.0 (1)模型调用能力
听说1.0是一个非常好用的版本,最后还是扛不住听说的压力,为了落实自己悬浮心理,自己还是着手实践一下了。 第一步pom集成: 参考spring-projects/spring-ai | DeepWiki维基以及官方文档入门 :: Spring AI …...
如何在 Manjaro Linux 上启用 AUR 仓库来安装软件包
Manjaro 是基于 Arch 的系统,是了解和学习 Arch Linux 命令的绝佳方式。它自带所有流行的桌面环境界面,无论是 XFCE 还是 Gnome 的爱好者,都可以在 Manjaro 中直接使用。 Manjaro 或 Arch Linux 的默认软件包管理器是 Pacman,我们…...
简单使用python
本文章没有深入探讨python,只说语法格式,合适于有其他编程语言的基础、并想快速使用python的人查看。 一、print() 用于打印信息,括号中可以是数学运算表达式或者字符串(或者说是文字)。 print(hello!) 1.1、转义字…...
2025服务端java搭建篇:蜻蜓I即时通讯系统私有化部署深度指南-优雅草卓伊凡|麻子|贝贝
2025服务端java搭建篇:蜻蜓I即时通讯系统私有化部署深度指南-优雅草卓伊凡|麻子|贝贝 前言 蜻蜓I即时通讯系统是一款不依赖第三方服务的私有化即时通讯解决方案,本指南将详细介绍如何使用宝塔面板在CentOS系统上完成系统的完整部署。私有化部署意味着您…...
用Streamlit开发第一个Python应用程序
用Streamlit开发第一个Python应用程序 Using Streamlit to Develop the First Application in Python By JacksonML 1.Streamlit简介 Streamlit是个新出世的、功能强大的Python第三方库,将为基于Web的Python应用程序大放异彩。 Streamlit官网主页面如下&#x…...
IDEA + Spring Boot + javadoc 实例应用
1、添加 javadoc 插件 依赖 pom.xml <build><plugins><!-- javadoc 插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-javadoc-plugin</artifactId><version>3.6.3</version><…...
【机器学习深度学习】交互式线性回归 demo
目录 一、环境准备 二、Demo 功能 三、完整交互 demo 代码 3.1 执行代码 3.2 示例交互演示 3.3 运行结果 3.4 运行线性图 使用 PyTorch 构建交互式线性回归模型:输入数据、拟合直线、图像可视化并实现实时预测,助你深入理解机器学习从数据到模型的…...
新手向:Anaconda3的安装与使用方法
我们在刚开始接触Python时使用的是Python的直接编译器,如果我们需要进行其他的项目编写往往需要使用另一个版本的Python ,这样反复的下载很是麻烦并且还会造成系统变量的紊乱.这次我们引入Anaconda3,可创建虚拟的Python环境,满足不同项目的需要,当不用的时候可以直接放心删除不…...
详解零拷贝
目录 一、用户态(User Mode)和内核态(Kernel Mode) 1.1 用户态 (User Mode): 1.2 内核态 (Kernel Mode): 1.3 关键交互:系统调用 (System Call) 二、为什么需要区分用户态和内核态&#x…...
微服务常用的基础知识
1.微服务介绍 1.1 产生背景 随着互联网的发展,网站应用的规模不断扩大,传统单体架构逐渐难以应对大型网站高并发、高扩展性等需求,于是分布式系统架构应运而生。Spring Cloud 就是在这种背景下诞生的,它利用 Spring Boot 的开发便…...
【开源工具】Windows一键配置防火墙阻止策略(禁止应用联网)| 附完整Python源码
🛡️【开源工具】Windows一键配置防火墙阻止策略(禁止应用联网)| 附完整源码 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热情源自每一个灵感闪现的夜晚。愿以开源之火,点亮前行之路。 🐋 希望大家多多支持,…...
6月份最新代发考试战报:思科华为HCIP HCSE 考试通过
6月份最新代发考试战报:思科华为HCIP HCSE 考试通过 H19-423 HCSA-Presales-IP Network 数通考试通过, H12-725 HCIP-Security安全 考试通过,H13-121 HCIP-Kunpeng Application Developer鲲鹏计算 考试通过,CCNP 350-401考试通过…...
本地部署开源时间跟踪工具 Kimai 并实现外部访问( Windows 版本)
Kimai 是一款开源的时间跟踪工具,它易于使用,并提供了强大的报告功能,在个人和团队记录工作时间、项目时间和活动时间等之后可以帮助用户了解他们是如何花费时间的,从而提高生产力和效率。本文将详细介绍如何在 Windows 系统本地部…...
SpringBoot 中 @Transactional 的使用
SpringBoot 中 Transactional 的使用 一、Transactional 的基本使用二、Transactional 的核心属性三、使用避坑(失效场景)3.1 自调用问题3.2 异常处理不当3.3 类未被 Spring 管理3.4 异步方法内使用失效 四、工作实践4.1 事务提交之后执行一些操作4.2 事…...
Mac电脑安装iTerm2通过rz命令上传文件到远程服务器
背景 闲着没事买了个云服务器玩(京东云轻量云主机),Mac本地搞了个java的jar包,想上传到云服务器,通过scp命令在Mac自带的【终端】上怎么都上传不了,如图。但是通过ssh命令(ssh root主机IP &…...
供应链数据可视化大屏
在全球化与数字化转型的双重浪潮下,供应链管理正面临前所未有的挑战:黑天鹅事件频发、多环节协同效率低下、库存与成本难以平衡……如何让供应链更透明、更敏捷、更具韧性?供应链数据可视化大屏应运而生,成为企业破解管理痛点的关…...
A2O MAY登上央视《中国音乐TOP榜》舞台,展现新歌榜冠军实力
——A2O MAY凭借新歌《BOSS》登上中国QQ音乐新歌榜冠军后,成功出演CCTV音乐节目《中国音乐TOP榜》,以实力赢得瞩目。 由A2O Entertainment(以下简称A2O)推出的全球女团 A2O MAY(成员包括朱晨予CHENYU、李诗洁SHIJIE、…...
关于如何在 Git 中切换到之前创建的分支的方法
文章目录 关于如何在 Git 中切换到之前创建的分支的方法一、确保你在项目目录中二、查看所有分支(可选)三、切换到目标分支四、如果分支仅在远程存在五、验证是否切换成功六、常见问题处理七、总结命令流程 PS:下次进入分支时,只需完成步骤1 …...
vue3+element-plus 组件功能实现 上传功能
一、整体功能概述 这段代码实现了一个基于 Vue 3 和 Element Plus 组件库的文件导入及预览功能模块。主要包含了一个主导入对话框(用于上传文件、展示文件相关信息、进行导入操作等)以及一个用于预览文件内容的预览对话框。支持导入特定格式(…...
多相机人脸扫描设备如何助力高效打造数字教育孪生体?
在教育数字化转型浪潮中,数字孪生体作为现实教育场景的虚拟映射,正成为智慧教育发展的关键技术支点。传统教育模式面临师资资源分布不均、个性化教学难以覆盖、跨时空教学场景受限等痛点,而数字孪生体通过构建高仿真虚拟教育主体(…...
高中成绩可视化平台开发笔记
高中成绩可视化平台(1) 一、项目概述 本系统是一个基于 PyQt5 和 Matplotlib 的高中成绩数据可视化分析平台,旨在帮助教师快速了解学生成绩分布、班级对比、学科表现等关键指标。平台支持文科与理科的数据切换,并提供多个维度的图…...
圆周期性显示和消失——瞬态实现(CAD c#二次开发、插件定制)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Timers; [assembly: CommandClass(typeof(IfoxDemo.Commands))] namespace IfoxDemo {// 新增的圆形闪烁命令实…...