
简介PsychoPy 是一套用于运行心理学和神经系统实验的开源工具包它把 Python 的简洁语法与 OpenGL 的高性能渲染结合起来帮助研究者快速呈现视觉、听觉刺激记录按键、反应时与眼动数据是 Matlab 商业方案之外的免费替代。该资源以 zip 压缩包形式提供大小约 17.5MB便于离线保存和迁移使用压缩包内文件清单未单独标注。已有 502 人学习浏览适合具备基础 Python 知识、希望摆脱商业授权限制的心理学与认知神经科学领域研究者、学生及实验课程教师。解压后即可在 Python 环境中调用并可使用 Builder 与 Coder 两种模式Builder 适合图形化快速搭建实验流程Coder 则提供更自由的脚本控制配合开源社区大量扩展库能够覆盖从简单反应时到 fMRI 同步等多层次任务范式显著降低实验编程门槛让研究者更专注于科学问题本身。 拿到一个名为psychopy, 用于运行心理学和神经系统实验.zip的压缩包时多数人的第一反应是这又是一个装了没时间研究的软件。但如果你恰好是要做行为实验、脑电实验或者需要精确控制刺激呈现时间的心理学/神经科学研究者那这个压缩包可能比一篇论文草稿还值钱。PsychoPy 是心理学实验编写领域绕不开的工具它能做视觉、听觉、触觉刺激呈现能精确记录按键反应时能和脑电、眼动、生理多导仪做同步触发而且完全免费、跨平台。最近很多人在后台问这个压缩包怎么用、里面装了什么、拿到手之后第一步做什么。我自己的经验是多数人卡住不是因为 PsychoPy 本身难学而是因为拿到安装包/环境包之后“不知道先点哪里”。这篇文章我就从一个打包好的实验环境出发把 PsychoPy 从解压、环境确认、跑通第一个实验到排查典型坑整条链路走一遍。1. 内容整体设计与思路拆解1.1 这个压缩包里到底装了什么一个命名为“psychopy, 用于运行心理学和神经系统实验.zip”的压缩包通常包含三类东西一是 PsychoPy 的安装文件或者便携版环境二是实验代码文件.py或者.psyexp工程文件三是实验素材和说明文档图片、音频、按键映射表、README。我第一次拿到类似压缩包时习惯先做一件事解压后不要急着双击任何 exe 或 py 文件先看目录结构。一个规范的实验包一般长这样psychopy_experiment_package/ ├── environment/ │ └── psychopy_installer_2024.2.5.exe ├── experiments/ │ ├── visual_search/ │ │ ├── visual_search_lastrun.py │ │ ├── visual_search.psyexp │ │ └── stimuli/ │ │ ├── target_red.bmp │ │ └── distractor_blue.bmp │ └── stroop_task/ ... ├── data/ │ ├── participant_01.csv │ └── participant_02.csv ├── analysis/ │ └── preprocessing.py └── README.md如果你拿到的包基本符合这个结构恭喜你这大概率是某个课题组的完整实验环境。如果只有孤零零几个.py文件也别慌——说明对方已经把环境剥离了你只需要自己装一个 PsychoPy把代码文件放进去直接跑就行。1.2 为什么选 PsychoPy 而不是 E-Prime 或 MATLAB这是很多新人最容易纠结的问题。我个人的看法是如果你的实验涉及灵活试次结构、需要和 Python 生态联动、或者预算有限PsychoPy 几乎是唯一解。首先要厘清一个概念PsychoPy 本身是 Python 库但它提供两种使用方式Builder 视图和Coder 视图。Builder 是图形化拖拽界面适合不熟悉编程的人快速搭简单实验Coder 是纯代码环境适合复杂逻辑和精细控制。和 E-Prime 对比PsychoPy 最大的优势是价格——E-Prime 的正版授权费对个人研究者来说不是小数目而 PsychoPy 完全开源免费。和 MATLAB Psychtoolbox 对比PsychoPy 的学习曲线更平缓而且 Python 生态下做数据分析pandas、scipy、机器学习可以无缝衔接不用再把数据倒来倒去。更重要的是PsychoPy 对时间精度的控制做得相当好。视觉刺激的刷新和屏幕的垂直同步vertical sync紧密配合在标准 60Hz 显示器上可以把刺激呈现时间控制在 16.7ms 的整数倍内。这一点对于反应时实验、阈上/阈下知觉实验来说是硬指标。2. 核心细节解析与实操要点2.1 环境准备Python 版本、依赖包与安装避坑如果你是新手我强烈建议不要手动去配 Python 环境。PsychoPy 对依赖库的版本要求比较敏感手动 pip install 容易把版本搞乱。直接用官方安装包Standalone Installer是最省心的方式——它会自带一个独立的 Python 环境你不需要管系统里已有的 Python 是什么版本。安装时有三个容易被忽略的地方安装路径不要带中文。PsychoPy 的底层依赖尤其是 wxPython、pyglet 这些对中文路径支持不稳定放在D:\Programs\PsychoPy这类纯英文路径下最稳。Windows 用户注意杀毒软件。第一次运行 PsychoPy 时部分杀软会拦截它生成临时脚本这属于误报加入信任区即可。显卡驱动要更新。如果实验里用了较多的动态视觉刺激Gabor patch、随机点运动集显可能撑不住高刷新率最好用独显跑并确认驱动是近一年内的版本。装好之后在 Coder 视图里输入以下代码验证环境from psychopy import visual, core win visual.Window(size[800, 600], screen0, winTypepyglet, unitspix) msg visual.TextStim(win, textPsychoPy OK!, colorwhite, height30) msg.draw() win.flip() core.wait(1.0) win.close()如果屏幕上出现一个白色窗口并显示出 “PsychoPy OK!”说明环境正常。如果报错99% 的情况是显卡驱动或者窗口后端winType的问题把pyglet改成glfw再试一次。2.2 Builder 视图与 Coder 视图怎么选这两个视图是 PsychoPy 使用中最核心的概念很多人一开始没搞明白导致后面走弯路。Builder 视图的操作逻辑是“搭积木”你把视觉刺激组件、按键反应组件、循环组件拖到流程线上设置好各自参数然后点运行。它的优点在于可视化和易上手特别适合固定流程的简单实验比如“先呈现十字注视点→呈现刺激→等待按键→结束”。生成的.psyexp文件本质上也是一个 Python 脚本的封装点击运行时PsychoPy 会自动把它转换成可执行的_lastrun.py脚本。Coder 视图则是直接写 Python 代码。控制粒度更细可以做动态试次、随机化算法、实时条件跳转也方便复用函数。我自己的习惯是流程简单时用 Builder 快速搭骨架然后切到 Coder 微调——因为很多精细参数比如注视点闪烁频率、背景色的动态渐变在 Builder 的属性面板里没那么直观写代码反而更高效。这里有一个实操中的经验Builder 和 Coder 可以混用。比如你在 Builder 里搭好了视觉刺激组件生成脚本后可以手动添加一段代码块Code Component在组件之间插入自定义 Python 逻辑。这是最常用的操作方式既保留可视化的易维护性又获得代码的灵活性。3. 实操过程与核心环节实现3.1 跑通经典 Stroop 实验从代码到数据理论讲再多不如亲手跑一个实验。我以心理学入门必做的Stroop 效应为例带你在 PsychoPy 中完整实现“刺激呈现—按键反应—数据记录”全流程。Stroop 实验的核心逻辑很简单屏幕中央呈现一个颜色词如“红”字体颜色可能一致红色也可能不一致蓝色被试的任务是判断字体颜色而不是词义按下对应按键。由于自动化加工的词义会干扰颜色判断不一致条件下的反应时显著长于一致条件。用 Coder 视图实现from psychopy import visual, core, event, data, gui import random # 设置窗口 win visual.Window(size[1024, 768], colorblack, unitspix) # 创建文本刺激 fixation visual.TextStim(win, text, colorwhite, height40) word_stim visual.TextStim(win, text红, colorred, height80) # 颜色映射 color_map {红: red, 蓝: blue, 绿: green} word_list [红, 蓝, 绿] # 收集被试信息 exp_info {participant: , age: } dlg gui.DlgFromDict(exp_info, title被试信息) if not dlg.OK: core.quit() # 创建数据文件 data_file open(fdata_{exp_info[participant]}.csv, w) data_file.write(trial,word,color,response,rt\n) # 实验流程 for trial in range(30): word random.choice(word_list) color random.choice(word_list) word_stim.text word word_stim.color color_map[color] # 先呈现注视点 500ms fixation.draw() win.flip() core.wait(0.5) # 呈现刺激等待按键 word_stim.draw() win.flip() t_start core.getTime() keys event.waitKeys(maxWait2.0, keyList[r,b,g], timeStampedTrue) if keys: key, t_rt keys[0][0], keys[0][1] rt t_rt - t_start else: key, rt none, NA # 写入数据 data_file.write(f{trial},{word},{color},{key},{rt}\n) # 试次间隔 800ms core.wait(0.8) data_file.close() win.close()这段代码虽然精简但覆盖了 PsychoPy 中最核心的几块能力visual.TextStim文本刺激支持中文字符但前提是系统里有中文字体可用这一点后面会细说。event.waitKeys带时间戳的按键监听返回按键名和相对时间戳是计算反应时的标准方式。data_file 写入每试次实时写入 CSV防止实验中途崩溃导致数据全部丢失——这是我从一次惨痛教训中总结出来的习惯。gui.DlgFromDict实验开始前弹窗收集被试信息方便事后分组。3.2 时间精度控制为什么反应时不能只看毫秒做心理学实验的人最关心的一件事我记录的真是这个刺激呈现之后第 347ms 按的键吗PsychoPy 给你提供了两种时间参考core.getTime()和win.flip()。核心要记住一点刺激真正呈现到屏幕上的时刻是win.flip()返回的时间而不是你调用word_stim.draw()的那一刻。因为 draw() 只是把刺激绘制到了后台缓冲区真正切换到前台显示需要等待下一个垂直刷新周期。所以严格的做法是这样t_stim_onset win.flip() # 记录实际呈现时刻这也解释了为什么刺激呈现间隔要控制在刷新率的整数倍。60Hz 显示器一帧是 16.7ms如果你的刺激呈现时间是 250ms实际可能是 250.2ms 或 266.7ms跳了一帧。对于反应时实验这点误差通常可以接受但要意识到它的存在。如果你的实验需要亚毫秒级时序比如视觉掩蔽范式建议关注两个方向使用winTypepyglet或glfw两者在时间精度上比默认的 pygame 后端更稳定。用psychopy.hardware模块对接专用同步设备如 Display、ViewPixx或者用光电二极管校准屏幕延迟。3.3 脑电实验的触发并行口与串口很多神经科学场景需要 PsychoPy 同时给脑电放大器发送触发标记。最常用的方案是并行口LPT触发。PsychoPy 里通过psychopy.hardware.parallel模块发送脉冲from psychopy.hardware import parallel port parallel.ParallelPort(address0x378) # 0x378 是 LPT1 默认地址 port.setData(0) # 清空 port.setData(1) # 发送 trigger 1 core.wait(0.005) port.setData(0) # 结束脉冲这里有个很容易踩的坑现代笔记本和多数台式机都没有物理并行口买了 USB 转 LPT 转接线也未必能直接工作因为驱动不一定把虚拟地址映射到 0x378。建议在正式实验前用世面上成熟的测试工具如 PortTest确认端口可写入再让被试进实验室。如果放大器支持串口或网络触发UDP也可以参考官方文档的psychopy.hardware.serial模块原理类似。4. 常见问题与排查技巧实录4.1 高频报错速查表我整理了近段时间被问到最多的几个问题做成一张速查表现象原因解决方案中文文字显示为方框/乱码默认字体不支持中文在 TextStim 中指定中文字体如fontSimHei或fontMicrosoft YaHei运行报错No module named psychopyPython 环境不是 PsychoPy 自带的那个检查是否在 Coder 视图内运行独立版需通过 Standalone 启动win.flip()很慢/画面卡顿显卡驱动问题或窗口后端不稳定更新显卡驱动尝试winTypeglfw关闭其他占用 GPU 的程序反应时数据全是同一个值数据记录方式错误确认使用了event.waitKeys(..., timeStampedTrue)否则按键时间不精确实验结束无法生成 CSV数据文件未关闭脚本结束前调用data_file.close()或改用with open(...) as f写法4.2 中文文字显示的深坑中文显示问题值得单独拿出来说因为国内研究者的实验基本离不开中文词刺激。PsychoPy 底层用的字体渲染库默认字体是 Arial不支持中文所以你在 TextStim 里设置text红时屏幕上很可能会出现一个空方块。正确的做法是显式指定一个支持中文的字体中文 visual.TextStim(win, text红, fontSimHei, colorred, height50)实操中推荐使用SimHei黑体或Microsoft YaHei微软雅黑这两个字体在 Windows 上默认存在笔画清晰适合实验刺激呈现。Mac 用户可以用Arial Unicode MS或PingFang SC。另外注意如果实验素材中含中文图片文件名也可能因为编码问题报错。建议所有刺激文件名统一改成拼音或英文避免 GBK/UTF-8 编码混乱带来的诡异错误。4.3 实验前必须在“非正式被试”身上跑一遍完整流程这是我反复强调的习惯每一次正式实验之前找一个不当被试的人或者你自己完整跑一遍程序。为什么要多这一步因为脚本在语法上没问题、在调试窗口里能运行和在被试机全屏模式下表现良好是两码事。我遇到过的情况包括全屏后刺激偏左导致按键映射错位、某台电脑上字体渲染过慢导致时间戳偏差、脑电触发端口被其他程序占用导致同步失败——这些只有完整跑一遍流程才能暴露出来。具体执行标准跑完整实验不是只跑前几个试次是完整跑到数据文件生成。切换被试机/实验室电脑再跑一遍确保不只在开发机上正常。检查生成的数据文件列名是否正确、RT 值是否有异常、试次数是否匹配。写在最后的小经验给刚开始用 PsychoPy 的朋友一个建议不必一上来就追求代码的完美和架构的优雅先从复制一个能跑的实验开始然后在它的基础上一点点加需求。这个工具最迷人的地方在于你从“会用”到“能完成一篇论文的全部实验”之间的距离其实比想象中短得多。我自己带的很多学生第一周还在问“怎么装”第二周已经能写出带注视点、反馈、随机分组的完整实验脚本了。另外一个非常实用的技巧在脚本开头加几行打印语句把关键事件时间戳打到控制台。这样万一实验中途出错你至少能知道是在哪一个环节崩的——排查效率高很多。希望这篇内容能帮你把手里的压缩包变成真正能出数据的实验。如果你跑的过程中遇到这里没提到的问题大概率是环境差异导致的不妨先检查一下系统版本、显卡驱动和 PsychoPy 版本这三样八成能找到答案。本文还有配套的精品资源点击获取