Python火柴人动画优化:替代clear_output()及提升流畅度方案问询
问题解答
1. 更简洁的实现方式
当前代码存在大量重复的print+sleep+clear_output逻辑,且导入了很多未使用的库(如numpy、pandas等),可以通过以下方式简化:
- 移除未使用的库,减少冗余;
- 将所有动画帧整理成模板列表,通过循环遍历实现帧播放,避免重复代码;
- 统一管理颜色和帧内容,提升代码可维护性。
2. 解决闪烁与窗口大小一致问题
clear_output()会清空整个输出区域,导致明显闪烁。替代方案是使用ANSI光标控制序列将光标定位到输出区域的左上角,然后直接覆盖打印新帧,而非清空整个窗口。同时要确保每个动画帧的行数、每行长度完全一致,避免窗口大小跳变。
优化后的代码
import time import sys class Color: PURPLE = '\033[95m' CYAN = '\033[96m' RED = '\033[91m' YELLOW = '\033[93m' BOLD = '\033[1m' END = '\033[0m' # 定义所有动画帧模板,确保每个帧的行数和宽度一致 ANIMATION_FRAMES = [ # 帧1 rf""" O o_/{Color.BOLD + Color.YELLOW}{{winner_initial}}{Color.END}\_o | / \ """, # 帧2 rf""" O {Color.BOLD + Color.RED}O{Color.END}_/{Color.BOLD + Color.YELLOW}{{winner_initial}}{Color.END} | / \ """, # 帧3 rf""" O {Color.BOLD + Color.YELLOW}{{winner_initial}}{Color.END}--{Color.BOLD + Color.RED}O{Color.END} | / \ """, # 帧4 rf""" O {Color.BOLD + Color.YELLOW}{{winner_initial}}{Color.END}-- {Color.BOLD + Color.RED}O{Color.END} | / \ """, # 帧5 rf""" O {Color.BOLD + Color.YELLOW}{{winner_initial}}{Color.END}-- {Color.BOLD + Color.RED}O{Color.END} | / \ """, # 帧6 rf""" O {Color.BOLD + Color.YELLOW}{{winner_initial}}{Color.END}-- {Color.BOLD + Color.RED}O{Color.END} | / \ """, # 帧7 rf""" O {Color.BOLD + Color.RED}O{Color.END} _/{Color.BOLD + Color.CYAN}{{loser_initial}}{Color.END}\_ | / \ / \ """, # 帧8 rf""" O {Color.BOLD + Color.RED}O{Color.END} _/{Color.BOLD + Color.CYAN}{{loser_initial}}{Color.END}\_ | / \ / \ """, # 帧9 rf""" O {Color.BOLD + Color.RED}O{Color.END} _/{Color.BOLD + Color.CYAN}{{loser_initial}}{Color.END}\_ | / \ / \ """, # 帧10 rf""" O {Color.BOLD + Color.RED}O{Color.END} |_/{Color.BOLD + Color.CYAN}{{loser_initial}}{Color.END} | / \ / \ """, # 帧11 rf""" O {Color.BOLD + Color.RED}|_/{Color.BOLD + Color.CYAN}{{loser_initial}}{Color.END} | / \ / \ """, # 帧12 rf""" {Color.BOLD + Color.RED} O |_/{Color.BOLD + Color.RED}{{loser_initial}}{Color.END} | / \ / \ """, # 帧13 rf""" {Color.BOLD + Color.RED} \|/ \/ \/ \/ \/ """ ] def fatality(winner, loser): winner_initial = winner.name[0] loser_initial = loser.name[0] # 遍历所有帧 for frame_template in ANIMATION_FRAMES: # 替换模板中的变量 frame = frame_template.format(winner_initial=winner_initial, loser_initial=loser_initial) # 使用ANSI序列将光标移到左上角,覆盖之前的内容 sys.stdout.write('\033[H') sys.stdout.write(frame) sys.stdout.flush() time.sleep(0.5) class TempClass: def __init__(self, name): self.name = name if __name__ == "__main__": temp1 = TempClass("M") temp2 = TempClass("P") fatality(temp1, temp2)
关键优化点说明
- 移除冗余依赖:删除了未使用的
numpy、pandas、datetime等库; - 帧模板化管理:把所有动画帧存入列表,通过循环播放,大幅减少重复代码;
- 光标控制替代清空:使用
\033[H将光标定位到输出区域左上角,直接覆盖打印新帧,避免清空整个窗口导致的闪烁; - 统一帧尺寸:所有帧保持相同的行数和空白填充,确保输出窗口大小稳定,动画更流畅;
- 代码规范:类名采用大驼峰命名,变量名更清晰,提升可读性。
内容的提问来源于stack exchange,提问作者user2461546
相关产品推荐
相关产品推荐

