Python Unicode仅在unix系统上读取文件时出错

Python Unicode仅在unix系统上读取文件时出错,python,python-3.x,Python,Python 3.x,我正在尝试使用Python3.7读取一个(大)文本文件。我在做一些琐碎的事情: with open(filename,'r') as f: for il,l in enumerate(f,il): %do things 如果我在windows上从Spyder的IPython控制台运行脚本,这将非常有效 但是,如果运行完全相同的脚本从unix服务器读取完全相同的文件(不是副本!),则会出现以下错误: File "/net/atgcls01/data2/j0266060

我正在尝试使用Python3.7读取一个(大)文本文件。我在做一些琐碎的事情:

with open(filename,'r') as f:
    for il,l in enumerate(f,il):
        %do things
如果我在windows上从Spyder的IPython控制台运行脚本,这将非常有效

但是,如果运行完全相同的脚本从unix服务器读取完全相同的文件(不是副本!),则会出现以下错误:

  File "/net/atgcls01/data2/j02660606/code/freeGSA.py", line 127, in read_gwa
    for il,l in enumerate(f,il):
  File "/u/lon/lamerio/.conda/envs/la3.7/lib/python3.7/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 2099: invalid start byte
我试图找到罪犯以了解发生了什么事。我做到了:

bytes = []
fobj = open(settings['GSA_file'],'rb')
for i in range(3000):
    b = fobj.read(1)
    bytes.append((i, b, b.hex()))

fobj.close()
bytes[2095:2105]
输出是

[(2095, b'0', '30'), (2096, b'0', '30'), (2097, b' ', '20'), (2098, b't', '74'), (2099, b'o', '6f'), (2100, b' ', '20'), (2101, b'5', '35'), (2102, b'6', '36'), (2103, b'1', '31'), (2104, b' ', '20')]
我在2099位置没有看到任何0xb0字符。实际上,位置2098是0x74,位置2099是0x6f,位置2100是0x20。这些转换为有效的utf-8字符“t”、“o”和“”(空格),它们确实位于文件中的2099位置

我如何解决这个错误?为什么它只出现在unix机器上

编辑: 运行

在两个系统上返回B
“utf-8”


注:在windows上我有3.7.5版,而在unix上我有3.7.4版。

这是一个Unicode字符,您可以使用“unidecode”模块对其进行解码。这将非常有效


您可以在此处阅读更多信息:

问题可能在于默认编码。如果是windows,则可能不是utf8,而是一些windows编码。在波兰,默认编码是
cp1250
,这样的代码可以工作

打开(文件名为'r',enccoding=“cp1250”)作为f的
:
对于il,枚举中的l(f,il):
%做事

在unix计算机上,请重试

将open(filename,encoding='latin-1')作为f:…

将open(filename,encoding='windows-1252')作为f:…


编辑:Windows的默认编码与UNIX不同(通常)。我假设您在windows计算机上编辑/创建了这些文件。您也可以打开其中一个文件,我相信使用记事本,它会在右下角显示编码。我可能错了,因为我是凭记忆回忆起来的。在任何情况下,这都是您希望在UNIX计算机上指定的编码。但请继续尝试我指定的两种编码。

您正在使用的python版本是什么?python 3.7。谢谢你指出我没有具体说明。我将其添加到问题中,您在2099处看不到字符的原因可能是因为文件前面有其他(有效)多字节字符。以unicode格式读取时,这些字符将被正确解释并显示为单个字符。在二进制模式下读取时,每个字符将占用多个字符,并在以后的输入中移动非unicode字符。您可以运行
fobj.read().find(b'\xb0')
来查找问题字符。但是为什么我在windows上没有得到错误?而且,unicode字符0xb0是我的文件中绝对没有的“°”符号,我不会直接转到另一个包,因为这是您正在处理的另一个依赖项。该错误源于UNIX和Windows具有不同的默认编码。如果你想知道错误的来源(这是一种很好的思维方式),可能首先要阅读编码。我在windows上遇到了同样的错误,我尝试将其编码为UTF-8,但这对我不起作用,这个包解决了我的问题。即使
sys.getdefaultencoding()
返回
'UTF-8'
,如果我将函数修改为
open(…,encoding='utf-8')
,错误也会在windows上重现。将行更改为
encoding='latin-1'
解决了该问题。我仍然不清楚为什么如果
sys.getdefaultencoding()
'utf-8'
open
在不指定编码时可以读取文件,但在指定
encoding='utf-8'
时返回了一个错误,这应该是默认值。有时编码很奇怪,可能需要一些段落来详细说明。根据我个人的经验,当出现这样的错误时,尝试上述编码在大约90%的情况下有效。至于为什么windows声称有一个默认的utf-8编码,或者在似乎切换编码时到底发生了什么,我也无法解释。很高兴它现在能工作了!
import sys
sys.getdefaultencoding()