我有以下代码以二进制方式将ASCII“@”字符写入文件:
fin=open('a.bin','wb')
fin.write('\x40')
fin.close()
事实证明,“@”字符已写入“a.bin”,其长度为1个字节。
但是,当我尝试编写一个unicode字符时:
fin=open('a.bin','wb')
fin.write(u'\x40')
fin.close()
事实证明“a.bin”仍然是1字节长。我认为它应该是2字节长,因为unicode字符占用2个字节。我可能会忽略一些微不足道的事情。
答案 0 :(得分:7)
您将Unicode与编码混淆。编码是一种标准,表示文本在0-255(字节)范围内的各个值的范围内,而Unicode是描述表示文本字形的代码点的标准。这两者是相关的,但不是同一件事。
Unicode标准包括几种编码。 UTF-16是一个这样的编码,每个代码点使用2个字节,但它不是标准中包含的唯一编码。 UTF-8是另一种这样的编码,它使用每个代码点的变量字节数。
但是,您的文件是使用ASCII编写的,这是Python 2在未指定显式编码时使用的默认编解码器。如果您希望每个代码点看到 2 字节,请明确编码为UTF-16:
fin.write(u'\x40'.encode('utf16-le')
以 little endian 字节顺序写入UTF-16;还有一个utf16-be
编解码器。通常,对于UTF-16或UTF32等多字节编码,您还需要包含BOM或字节顺序标记;当您编写UTF-16而不选择任何endianes时,它会自动包含。
fin.write(u'\x40'.encode('utf16')
我强烈敦促您在继续之前研究Unicode,编解码器和Python:
答案 1 :(得分:1)
答案 2 :(得分:1)
Martijn的回答是正确的:首先了解有关Unicode的更多信息。但是,阅读大型教育文件的答案可能更小:
在将Python unicode值(在您的情况下为u'\x40'
)写入流(在您的情况下为打开文件)时,必须将此抽象unicode值转换为具体的字节流。为此,使用编码。
您可以明确地执行此操作(使用u'\x40'.encode('foo')
),也可以隐式执行此操作;然后正在使用一些编码。在您的情况下,"ascii"
或"utf8"
都表示unicode- @为单个字节,值为40。
你似乎想要的正在使用一种编码,其中unicode- @表示为一个双字节值;例如,这将是编码utf-16
。