Anaconda Spyder中Pygame程序二次运行触发致命错误求助
问题分析与解决:Spyder中重复运行Pygame程序触发段错误
问题现象
在Anaconda的Spyder控制台中首次运行Pygame程序正常,第二次执行时触发致命的Fatal Python error: (pygame parachute) Segmentation Fault,仅能通过新建临时控制台临时解决,担心后续引发其他异常。
问题代码
import pygame from pygame.locals import * board = pygame.display.set_mode((400,600)) #colors black = pygame.Color(0, 0, 0) white = pygame.Color(255, 255, 255) grey = pygame.Color(128, 128, 128) red = pygame.Color(255, 0, 0) blue = pygame.Color(0, 0, 255) green=pygame.Color(0,255,0) board.fill(white) pygame.display.set_caption("Sigil") class Card (pygame.sprite.Sprite): def __init__(self,image,x,y): super().__init__() #above is magic class code that shouldn't be messed with (mostly) #inuit only happens once self.x=x self.y=y self.image=image self.rect = self.image.get_rect() board.blit(self.image,(self.x,self.y)) def update(self): if event.type == pygame.KEYDOWN: if event.key == pygame.K_w: self.rect.move_ip(0, -5) elif event.key == pygame.K_s: self.rect.move_ip(0,5) elif event.key == pygame.K_a: self.rect.move_ip(-5, 0) elif event.key == pygame.K_d: self.rect.move_ip(5, 0) def draw(self, surface): surface.blit(self.image, self.rect) test=pygame.image.load("Twitter-icon.png") #Make sure to add .png test=pygame.transform.scale(test,(test.get_width()/2,test.get_height()/2)) P1 = Card(test,10,10) print_message=pygame.USEREVENT + 0 pygame.time.set_timer(print_message, 3000) #can be used to make longer loops for your loop #Frames Per Second clock=pygame.time.Clock() #Game Loop while True: #All functions dependent on user input need to be part of this loop- event.get clears the event que for event in pygame.event.get(): if event.type == QUIT: pygame.quit() if event.type == print_message: print("Hello World") P1.update() board.fill(white) P1.draw(board) pygame.display.flip() clock.tick(20)
报错信息
Fatal Python error: (pygame parachute) Segmentation Fault Thread 0x00008390 (most recent call first): File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\parentpoller.py", line 97 in run File "C:\Users\HP\anaconda3\lib\threading.py", line 926 in _bootstrap_inner File "C:\Users\HP\anaconda3\lib\threading.py", line 890 in _bootstrap Thread 0x0000586c (most recent call first): File "C:\Users\HP\anaconda3\lib\site‑packages\zmq\sugar\socket.py", line 475 in recv_multipart File "C:\Users\HP\anaconda3\lib\site‑packages\jupyter_client\session.py", line 803 in recv File "C:\Users\HP\anaconda3\lib\site‑packages\spyder_kernels\comms\frontendcomm.py", line 114 in poll_one File "C:\Users\HP\anaconda3\lib\site‑packages\spyder_kernels\comms\frontendcomm.py", line 104 in poll_thread File "C:\Users\HP\anaconda3\lib\threading.py", line 870 in run File "C:\Users\HP\anaconda3\lib\threading.py", line 926 in _bootstrap_inner File "C:\Users\HP\anaconda3\lib\threading.py", line 890 in _bootstrap Thread 0x00005f14 (most recent call first): File "C:\Users\HP\anaconda3\lib\threading.py", line 296 in wait File "C:\Users\HP\anaconda3\lib\threading.py", line 552 in wait File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\history.py", line 829 in run File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\history.py", line 58 in needs_sqlite File "", line 2 in run File "C:\Users\HP\anaconda3\lib\threading.py", line 926 in _bootstrap_inner File "C:\Users\HP\anaconda3\lib\threading.py", line 890 in _bootstrap Thread 0x00006c64 (most recent call first): File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\heartbeat.py", line 100 in run File "C:\Users\HP\anaconda3\lib\threading.py", line 926 in _bootstrap_inner File "C:\Users\HP\anaconda3\lib\threading.py", line 890 in _bootstrap Thread 0x00006558 (most recent call first): File "C:\Users\HP\anaconda3\lib\selectors.py", line 314 in _select File "C:\Users\HP\anaconda3\lib\selectors.py", line 323 in select File "C:\Users\HP\anaconda3\lib\asyncio\base_events.py", line 1746 in _run_once File "C:\Users\HP\anaconda3\lib\asyncio\base_events.py", line 538 in run_forever File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\platform\asyncio.py", line 153 in start File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\iostream.py", line 78 in _thread_main File "C:\Users\HP\anaconda3\lib\threading.py", line 870 in run File "C:\Users\HP\anaconda3\lib\threading.py", line 926 in _bootstrap_inner File "C:\Users\HP\anaconda3\lib\threading.py", line 890 in _bootstrap Current thread 0x000060c8 (most recent call first): File "C:\Users\HP\Documents\Python Scripts\Cardgame(sigil)prototype.py", line 4 in File "C:\Users\HP\anaconda3\lib\site‑packages\spyder_kernels\customize\spydercustomize.py", line 377 in exec_code File "C:\Users\HP\anaconda3\lib\site‑packages\spyder_kernels\customize\spydercustomize.py", line 476 in runfile File "", line 1 in File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\interactiveshell.py", line 3331 in run_code File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\interactiveshell.py", line 3254 in run_ast_nodes File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\interactiveshell.py", line 3063 in run_cell_async File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\async_helpers.py", line 68 in _pseudo_sync_runner File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\interactiveshell.py", line 2886 in _run_cell File "C:\Users\HP\anaconda3\lib\site‑packages\IPython\core\interactiveshell.py", line 2858 in run_cell File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\zmqshell.py", line 536 in run_cell File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\ipkernel.py", line 300 in do_execute File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\gen.py", line 209 in wrapper File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\kernelbase.py", line 541 in execute_request File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\gen.py", line 209 in wrapper File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\kernelbase.py", line 268 in dispatch_shell File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\gen.py", line 209 in wrapper File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\kernelbase.py", line 361 in process_one File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\gen.py", line 748 in run File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\gen.py", line 787 in inner File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\ioloop.py", line 743 in _run_callback File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\ioloop.py", line 690 in File "C:\Users\HP\anaconda3\lib\asyncio\events.py", line 88 in _run File "C:\Users\HP\anaconda3\lib\asyncio\base_events.py", line 1782 in _run_once File "C:\Users\HP\anaconda3\lib\asyncio\base_events.py", line 538 in run_forever File "C:\Users\HP\anaconda3\lib\site‑packages\tornado\platform\asyncio.py", line 153 in start File "C:\Users\HP\anaconda3\lib\site‑packages\ipykernel\kernelapp.py", line 583 in start File "C:\Users\HP\anaconda3\lib\site‑packages\spyder_kernels\console\start.py", line 318 in main File "C:\Users\HP\anaconda3\lib\site‑packages\spyder_kernels\console\__main__.py", line 11 in File "C:\Users\HP\anaconda3\lib\runpy.py", line 85 in _run_code File "C:\Users\HP\anaconda3\lib\runpy.py", line 193 in _run_module_as_main
原因分析
- Pygame资源残留:首次运行后调用
pygame.quit()仅关闭窗口,Spyder的交互式控制台会保留全局变量和模块状态,第二次运行时pygame.display.set_mode()尝试重新创建窗口,触发资源冲突导致段错误。 - 代码逻辑问题:
update方法直接引用全局event变量,未通过参数传递,存在逻辑错误。- 渲染、更新操作嵌套在
event.get()循环内,每处理一个事件就执行一次渲染,逻辑混乱。 - 退出时仅调用
pygame.quit(),未终止程序循环,残留资源无法彻底释放。
解决方法
1. 修复代码结构,确保资源正确清理
修改后的代码:
import pygame from pygame.locals import * def main(): # 显式初始化Pygame pygame.init() board = pygame.display.set_mode((400,600)) pygame.display.set_caption("Sigil") # 颜色定义 black = pygame.Color(0, 0, 0) white = pygame.Color(255, 255, 255) grey = pygame.Color(128, 128, 128) red = pygame.Color(255, 0, 0) blue = pygame.Color(0, 0, 255) green=pygame.Color(0,255,0) class Card(pygame.sprite.Sprite): def __init__(self, image, x, y): super().__init__() self.image = image self.rect = self.image.get_rect(topleft=(x, y)) def update(self, event=None): if event and event.type == pygame.KEYDOWN: if event.key == pygame.K_w: self.rect.move_ip(0, -5) elif event.key == pygame.K_s: self.rect.move_ip(0,5) elif event.key == pygame.K_a: self.rect.move_ip(-5, 0) elif event.key == pygame.K_d: self.rect.move_ip(5, 0) def draw(self, surface): surface.blit(self.image, self.rect) # 加载图片并添加异常处理 try: test = pygame.image.load("Twitter-icon.png") test = pygame.transform.scale(test, (test.get_width()//2, test.get_height()//2)) except pygame.error: print("无法加载图片,请检查路径是否正确") return P1 = Card(test, 10, 10) print_message = pygame.USEREVENT + 0 pygame.time.set_timer(print_message, 3000) clock = pygame.time.Clock() running = True while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == print_message: print("Hello World") # 将事件传递给update方法 P1.update(event) # 渲染操作移到事件循环外,保证每帧只渲染一次 board.fill(white) P1.draw(board) pygame.display.flip() clock.tick(20) # 退出时彻底清理资源 pygame.quit() if __name__ == "__main__": main()
2. Spyder运行设置调整
- 打开运行配置(Run > Configuration per file),勾选在独立的外部系统终端中运行,避免交互式控制台的资源冲突。
- 每次运行前,在控制台输入
%reset -f,清除所有全局变量和模块状态后再执行程序。
关键修改说明
- 将代码封装在
main()函数中,确保每次运行都是独立的初始化流程,避免全局变量残留。 update方法通过参数接收event,避免引用全局变量的错误。- 渲染操作移到事件循环外部,保证每帧只执行一次渲染,逻辑更清晰。
- 添加
pygame.init()显式初始化,退出时设置running=False终止循环,再调用pygame.quit()彻底清理资源。 - 增加图片加载异常处理,避免因路径错误导致崩溃。
内容的提问来源于stack exchange,提问作者Jocylin Francis
相关产品推荐
相关产品推荐

