Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我很困惑_Python_Encoding_Utf 8_Endianness_Ucs2 - Fatal编程技术网

Python 我很困惑

Python 我很困惑,python,encoding,utf-8,endianness,ucs2,Python,Encoding,Utf 8,Endianness,Ucs2,我编辑了三个内容相同的文件“你"(英文是you)以三种不同的形式出现在it中——gbk\utf-8\ucs-2,gedit命名为“ok1,ok2,ok3” 事实上,f3是'\x60\x4f', 但是下面的输出让我感到困惑 >>> '\xe4\xbd\xa0'.decode("utf-8") u'\u4f60' >>> '\xc4\xe3'.decode("gbk") u'\u4f60' >>> 为什么ucs-2(或者说unicode)中只

我编辑了三个内容相同的文件“你"(英文是
you
)以三种不同的形式出现在it中——gbk\utf-8\ucs-2,gedit命名为“ok1,ok2,ok3”

事实上,f3是'\x60\x4f', 但是下面的输出让我感到困惑

>>> '\xe4\xbd\xa0'.decode("utf-8")
u'\u4f60'
>>> '\xc4\xe3'.decode("gbk")
u'\u4f60'
>>> 
为什么ucs-2(或者说unicode)中只有endian问题,utf-8中没有,gbk中也没有?utf-8和gbk将数据存储在字节序列中。在这些编码中,哪个字节值位于哪个字节值之后是严格定义的。这种字节顺序不会随编码、传输或解码中使用的体系结构而改变

另一方面,UCS-2或新的UTF-16以2字节的顺序存储数据。这些2字节令牌中单个字节的顺序是endianness,它取决于底层机器架构。系统必须就如何识别令牌的endianness达成一致,然后再与UCS-2中编码的数据通信


在您的情况下,Unicode点U+4F60在UCS-2中作为单个2字节标记编码。由于您的计算机在内存对齐中将最低有效字节放在最高有效字节之前,因此序列
('0x60','0x4F')
已放入文件中。因此,文件读取将按此顺序生成字节

Python仍然可以正确解码此数据,因为它将在形成2字节令牌之前以正确的顺序读取字节:

>>> '`O\n\x00'.decode('utf-16')
u'\u4f60\n'

Endian ness仅适用于多字节字,但UTF-8使用8位的单位来编码信息(这就是名称中的8所代表的)。在这里,从来没有顺序混乱的问题

有时它可能需要不止一个这样的单元来编码信息,但它们被认为是不同的。例如,字母
A
是一个字节,
0x41
。当它必须用更多字节来编码字符时,它会使用前导指示符字节,然后是额外的连续字节来捕获该字符所需的所有信息从逻辑上讲,这些是不同的单位

GBK使用类似的方案;字符使用1字节的单位,就像UTF-8一样,第二个字节可以用于某些字符

UCS-2(及其继任者UTF-16)另一方面,是一种2字节格式。它以16位为单位对信息进行编码,这16位总是在一起。该单位中的2个字节在逻辑上属于一起,现代体系结构将这些字节视为一个单元,因此决定了它们的存储顺序。这就是endianess的来源,即u中2个字节的顺序nit取决于体系结构。在您的体系结构中,字节是使用小尾数排序的,这意味着“较小”字节优先。这就是文件中
0x4F
字节位于
0x60
字节之前的原因

请注意,python可以很好地读取大尾端或小尾端UTF-16;如果开头没有指示符(字节顺序标记或BOM),则可以显式选择尾端:


在后一个示例中,字节被反转,并被解码为big-endian。

由于您的计算机在内存对齐中将最低有效字节放在最高有效字节之前,因此序列('0x60','0x4F')已放入文件中。因此,文件读取将按此顺序生成字节。为什么在我的计算机中,f1不是“\xe3\xc4\n”?f2不是f2'\xbd\xe4\xa0\n'@Dd Pp:因为在写入utf-8文件时,gedit会逐个放入字节。但是,在写入ucs-2编码文件时,gedit会将字节两个一个地放入。字节内的顺序取决于endianness仅适用于后一种情况。
>>> '`O\n\x00'.decode('utf-16')
u'\u4f60\n'
>>> '`O\n\x00'.decode('utf-16')
u'\u4f60\n'
>>> '`O\n\x00'.decode('utf-16-le')
u'\u4f60\n'
>>> 'O`\x00\n'.decode('utf-16-be')
u'\u4f60\n'