“串”有两个截然不同的概念:(1)字符串的字符,(2)数组字节。这种区别在很长一段时间内都被忽略了,不超过256个字符(ASCII,Latin-1,Windows-1252,Mac OS Roman,...):这些编码将一组常见字符映射到0到255之间的数字(即字节),保留在同一操作系统上的文本,就会有多种编码:这样的程序只会简单将文本视为字节(通过操作系统使用的编码)。根据以下两点正确地分离了这两个字符串概念:
1.
字符大多与计算机无关:可以在粉笔板等上绘制它们,例如بايثون,中python和蛇图形。机器的“字符”还包括“绘图指令”,例如空格,回车,设置书写方向的指令(用于阿拉伯语等),重音符号等
.Unicode标准中包含
非常大的字符列表。它涵盖了大多数已知角色。
2. 另一方面,计算机确实需要以某种方式表示抽象字符:为此,它们使用
字节数组(包括0到255之间的数字),因为它们的内存以字节块的形式出现。将字符转换为字节的必要过程称为编码。因此,计算机需要编码才能表示字符。计算机上存在的任何文本都会被编码(直到显示),无论是发送到终端(需要以特定方式编码的字符),还是保存在文件中。为了显示或正确地“理解”(例如,通过Python解释器),字节流被解码成字符。
一些编码(UTF-8,UTF-16,...)由Unicode定义为其字符列表(Unicode因此定义了这些字符的字符列表和编码 - 仍然有人将表达式“Unicode编码”视为UTF-8,但这是不正确的,因为Unicode提供了多种编码)。
总之,计算机需要在内部用字节表示字符,它们通过两个操作来完成:
编码:字符→字节
解码:字节→字符
某些编码不能编码所有字符(例如ASCII),而(某些)Unicode编码允许你编码所有Unicode字符。编码也不一定是唯一的,因为一些字符可以直接表示或作为组合表示(例如,基本字符和重音符号)。
现在,我所谓的“字符”就是Unicode所谓的“
用户感知角色 ”。单个字符有时可以通过组合Unicode列表中不同
索引处的字符部分(基本字符,重音符号......)来表示,这些字符部分称为“
代码点 ” - 这些代码点可以组合在一起形成一个“字形集群”。Unicode因此导致字符串的第三个概念,由一系列Unicode代码点组成,位于字节和字符串之间,并且更接近后者。虽然Python可以打印字符串,但
Python非字节字符串本质上是Unicode代码点的序列,而不是字符的
序列。代码点值是Python \u和\UUnicode字符串语法中使用的值。它们不应与字符的编码混淆(这有一个重要的结果:
Python(Unicode)字符串的长度是它的代码点数,它并不总是字符的数量:因此s ="\u1100\u1161\u11a8"; print(s, "len", len(s))(Python 3)각 len 3尽管s是一个韩语字符(因为它用3个代码点表示)。但是,在许多实际情况中,字符串的长度是其字符的数量,因为许多字符通常由Python存储为单个Unicode代码点。
在Python 2中,Unicode字符串被称为“Unicode字符串”(unicode类型,文字形式u"…"),而字节数组是“字符串”(str类型,其中字节数组可以例如用字符串文字构造"…")。在Python 3中,Unicode字符串简称为“字符串”(str类型,文字形式"…"),而字节数组则是“字节”(bytes类型,文字形式b"…")。
通过这几个关键点,你应该能够理解大多数与编码相关的问题!
通常,当你打印 u"…" 到终端时,你不应该得到一个图形:Python知道终端的编码。实际上,你可以检查终端的编码:
% python
Python 2.7.6 (default, Nov 15 2013, 15:20:37)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print sys.stdout.encoding
UTF-8
如果你的输入字符可以使用终端的编码进行编码,Python将这样做,并将相应的字节发送到你的终端而不会抱怨。然后终端将在解码输入字节后尽力显示字符(最坏的情况是终端字体没有一些字符,而是会打印某种空白)。
如果需要,可以通过环境变量
设置 stdin,stdout和stderr的编码PYTHONIOENCODING:
% PYTHONIOENCODING=UTF-8 python2.7 -c "import sys; print sys.stdout.encoding" | cat
UTF-8
你的第一个字符(\u001A)是不可打印的。