我想弄清楚在这种情况下发生了什么。我在Windows 7 64位上,我在Python中尝试使用Unicode。
使用以下Python代码
#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#aaaaaa
x = [u'\xa3']
f = open('file_garbage.txt', 'w+')
for s in x:
if s in f.read():
continue
else:
f.write(s.encode('utf-8'))
f.close()
我没有收到错误消息,file_garbage.txt包含
£
当我向x添加另一个项目时
#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#aaaaaa
x = [u'\xa3',
u'\xa3']
f = open('file_garbage.txt', 'w+')
for s in x:
if s in f.read():
continue
else:
f.write(s.encode('utf-8'))
f.close()
我收到了UnicodeDecodeError
Traceback (most recent call last):
File "file_garbage.py", line 9, in <module>
if s in f.read():
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 2: ordinal not in range(128)
file_garbage.txt将包含大约250行字节,如此
c2a3 4b02 e0a6 5400 6161 6161 6161 6161
6161 6161 6161 6161 6161 6161 6161 6161
6161 6161 6161 6161 6161 610d 0a23 6161
6161 6161 0d0a 0d0a 7820 3d20 5b75 275c
7861 3327 2c0d 0a20 2020 2020 7527 5c78
6133 275d 0d0a 0d0a 6620 3d20 6f70 656e
2827 6669 6c65 5f67 6172 6261 6765 2e74
像这样的垃圾
£Kà¦éaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#aaaaaa
x = [u'\xa3',
u'\xa3']
f = open('file_garbage.txt', 'w+')
for s in x:
if s in f.read():
continue
else:
f.write(s.encode('utf-8'))
f.close()
Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py.
iÿÿÿÿNt
后面跟着一堆ENQ,DC2,SOH,STX,NUL符号和链接:
C:\Python27\lib\encodings\cp1252.py
垃圾图片
我猜这是一个与编码和/或我处理文件的方式有关的问题,但我对确切发生的事情以及为什么结果看起来有所不同感到困惑。
只有在文件顶部看似随意的一对注释字符串但是总是会生成字节时,才会生成垃圾。
如果有帮助,我的系统编码设置如下:
sys.stdout.encoding : cp850
sys.stdout.isatty() : True
locale.getpreferredencoding() : cp1252
sys.getfilesystemencoding() : mbcs
答案 0 :(得分:2)
文件可能因为未正确关闭而损坏。我从未见过这种特殊的行为,但它属于可能性范畴。尝试更改代码以使用with
:
with open('file_garbage.txt', 'w+') as f:
# do your stuff here
这将确保即使引发异常也会关闭文件。
异常的原因是x
包含unicode字符串,但是当你读入f
时,你正在读取字节数。当您尝试检查s in f.read()
时,它会尝试将unicode字符串与文件中的字节进行比较,但会失败,因为文件中的字节不能解释为unicode。您需要将文件的内容解码回unicode。
您的代码还有一些其他问题,这些问题有些超出了本问题的范围。对于初学者来说,在这样的循环中使用f.read()
将不起作用,因为第一次读取将读取整个文件,后续读取将不返回任何内容。相反,首先将文件读取(并解码)为变量,然后对该变量进行比较。此外,我不确定以w+
模式读取和写入文件是否可以满足您的需求。 (我实际上并不确定您希望代码执行什么操作。)正如documented,w+
截断文件,因此您无法通过添加已经存在的内容来“更新”它