windows下Psychopy3保存文件中文乱码解决办法

快速查看解决办法请直接拖到文末第四部分


一、发现问题

最近在使用psychopy3时出现一件非常奇怪的事情:运行结束后保存的csv文件中文乱码并错行。

如图所示:instr是指导语变量,image_file是图片的路径。

二、实验背景描述

这是一个很简单的使用程序,我就直接用了psychopy图形化的builder窗口。这个实验用conditions.xlsx文件控制循环。因为不同的trial指导语不一样,在conditions里面写了一些中文的指导语。但在运行完该程序后,获取到的数据里面中文全部乱码而且有错列,例如本来应该两列的东西拼到了一列。但是在运行呈现的时候,展现出来的指导语都是中文,且正确。

结合windows下使用python的经验,我估摸着是windows的编码问题。

三、问题排除逻辑

3.1 先要确认是不是写文件的时候编码有误。

1、首先找到psychopy运行的lastrun.py代码,发现结尾部分的saveAsWideText函数定义了最终的文件存储。

2、接着找到saveAsWideText函数定义的地方,根据psychopy官网的Reference Manul (API)发现是在experiment Handler 里面定义了该函数,在github上也确认了这点。回到我的电脑,就 是在psychopy安装路径下的data\experiment.py文件里。我这电脑里是:D:\Program Files (x86)\PsychoPy3\Lib\site-packages\psychopy\data\experiment.py

3、找到249行 def saveAsWideText的地方,那里传入了encoding = 'utf-8'的参数,看上去没有问题。整个函数也很清晰,在写入文件的时候,作者是有提前考虑到编码问题了。

3.2 写文件的编码设为utf-8是正确的,是否打开conditions.xlsx文件时没有传入编码?

4、发现打开文件是在305行的openOutputFile函数里使用的,而该函数是从psychopy.tools.filetools里面导入的。于是查看filetools模块。找到94行发现OutputFile这个函数在传入参数的时候也默认了'utf-8',所以这个地方应该也没问题

def openOutputFile(fileName=None, append=False, fileCollisionMethod='rename',

                  encoding='utf-8'):

5、【顿悟】突然联想到之前在这个电脑上用python保存文件的时候,用utf-8不行,得用utf-8-sig,所以我把第3步saveAsWideText的encoding改成了'utf-8-sig'。再运行就没有乱码了(见下图)。

到这里基本上已经解决了主要问题。但是后续还会出现这种情况,需要进一步查明为什么utf-8在这里无效。首先一个个排除了.py文件的编码问题,全是utf-8。

3.3 接下来猜想可能是conditions.xlsx文件的编码问题,这玩意就不是utf-8的编码?新建了conditions.csv文件,在encoding = 'utf-8'的时候也这样,看来是别的原因了。

6、在python官网找到关于编码问题的解释,里面写到:"为了可靠的探测编码……微软为它的记事本程序发明了utf-8 with BOM,也就是(python里的utf-8-sig),特点是会在所有Unicode之前加上0xef, 0xbb, 0xbf……在python里面要避免这玩意儿。" 这可能就是windows系统的毛病了……

Without external information it’s impossible to reliably determine which encoding was used for encoding a string. Each charmap encoding can decode any random byte sequence. However that’s not possible with UTF-8, as UTF-8 byte sequences have a structure that doesn’t allow arbitrary byte sequences. To increase the reliability with which a UTF-8 encoding can be detected, Microsoft invented a variant of UTF-8 (that Python 2.5 calls "utf-8-sig") for its Notepad program: Before any of the Unicode characters is written to the file, a UTF-8 encoded BOM (which looks like this as a byte sequence: 0xef, 0xbb, 0xbf) is written. As it’s rather improbable that any charmap encoded file starts with these byte values (which would e.g. map to

LATIN SMALL LETTER I WITH DIAERESIS

RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK

INVERTED QUESTION MARK

in iso-8859-1), this increases the probability that a utf-8-sig encoding can be correctly guessed from the byte sequence. So here the BOM is not used to be able to determine the byte order used for generating the byte sequence, but as a signature that helps in guessing the encoding. On encoding the utf-8-sig codec will write 0xef, 0xbb, 0xbf as the first three bytes to the file. On decoding utf-8-sig will skip those three bytes if they appear as the first three bytes in the file. In UTF-8, the use of the BOM is discouraged and should generally be avoided.

7、github提交问题反馈给psychopy项目的成员

我在Psychopy项目里提了个issue描述了遇到的这个问题,项目组的成员@hoechenberger 告诉我,可能是因为使用EXCEL打开CSV文件的问题,建议我试试LibreOffice这个软件打开(见下图)。我在安装并修改csv的默认打开程序为LibreOffice后,这个问题就解决了!用LibreOffice打开这个csv文件是没问题的。终于找到了问题所在!!!

四、解决办法小结

解决办法1:

1、找到psychopy安装路径下的experiment文件,例如:PsychoPy3\Lib\site-packages\psychopy\data\experiment.py

2、把里面def saveAsWideText这一行的 encoding = 'utf-8' 改成 encoding = 'utf-8-sig',保存!!

3、再运行就OK了。

这种方法有个弊端,就是如果你不使用Excel而是用R语言处理最终的csv数据,那么在用R读入该文件的时候可能需要指定encoding = "utf-8-sig"。


解决办法2:

安装LibreOffice,并将之修改为.csv文件的默认打开程序,该问题就解决了。弊端:这个办法就是要新安装一个软件。

PS:顺便安利一下这个LibreOffice,最开始是在linux上使用的开源办公软件,相当于office之于windows。后来这个开源项目不断壮大,现在LibreOffice已经有中文版了,如果厌倦了每年都要破解office套件的同学可以试试这款软件。

五、根本原因

最终发现根本问题在于使用windows里EXCEL打开这个csv文件时,EXCEL默认给这个文件加了BOM,导致这个原本UTF-8编码的文件显示错乱。

也就是原本UTF-8编码的文件,EXCEL非要用UTF-8-sig的编码去打开,导致显示错乱。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 字符是用户可以读写的最小单位。计算机所能支持的字符组成的集合,就叫做字符集。字符集通常以二维表的形式存在。二维表的...
    刘惜有阅读 8,037评论 2 14
  • 字符集和编码简介 在编程中常常可以见到各种字符集和编码,包括ASCII,MBCS,Unicode等字符集。确切的说...
    兰山小亭阅读 8,416评论 0 13
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,423评论 0 13
  • 我一直有一种感觉,觉得自己内心脆弱,犹如孩子们手中的橡皮泥,被工作的压力扭曲变了形。这扭曲变了行的心态,又...
    兰亭晓荷阅读 141评论 1 1
  • 生 拂面的风吹着雪 在夜里飘落天空 熟睡中的田野醒了 酥软的表层 沙沙的响声 那是绿色低沉的声音 打翻了的调色板 ...
    达悟希阅读 186评论 2 3