为什么字符串和列表在 UNICODE(utf-8) 中有所不同?'-'怎么会出错呢?

Zho*_*hou 5 python unicode

>>> final=[]
>>> for a in range(65535):
        final.append([a,chr(a)])


>>> file=open('1.txt','w',encoding='utf-8')
>>> file.write(str(final))
960881
>>> file.close()
>>> final=''
>>> for a in range(65535):
        final+='%d -------- %s'%(a,chr(a))


>>> file=open('2.txt','w',encoding='utf-8')
>>> file.write(final)
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    file.write(final)
UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' in position 873642: surrogates not allowed
Run Code Online (Sandbox Code Playgroud)

如您所见,1.txt 已保存。为什么保存第二个“文件”(字符串)会出错?

Ste*_*ann 4

来自维基教科书

\n\n
\n

Unicode 和 ISO/IEC 10646 不会将实际字符分配给 D800\xe2\x80\x93DFFF 范围 \xe2\x80\x94 中的任何代码点,这些代码点仅在代理项对中使用时才有意义。因此,代理对中的单个代码点不代表字符,除非在代理对中使用,否则无效,并且

\n
\n\n

所以我想说chr(0xd800)already是无效的,我猜Python只是出于速度原因不检查它。但 UTF-8 编码器确实会检查它并抱怨。

\n\n

它适用于第一个文件的原因是,将字符串包装在列表中并str在该列表上使用会导致对repr字符串进行 -ing:

\n\n
>>> str( chr(0xd800) )\n\'\\ud800\'\n>>> str([chr(0xd800)])\n"[\'\\\\ud800\']"\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意列表版本中的双反斜杠。它不是一个“无效字符”,而是六个\\ud800有效字符\\ud、和。这些可以被编码。800

\n