Unicode 万国码
在 Python 3 中,字符串由 Unicode 表示,而不是字节。ASCII 码是定义字符数字代码的最著名的标准。数字值最初只定义 128 个字符,因此 ASCII 只包含控制代码、数字、小写字母、大写字母等。然而,我们不足以表示世界各地存在的重音字符、汉字或表情符号等字符。因此,Unicode 被开发来解决这个问题。它定义了代码点来表示各种字符,如 ASCII,但字符数多达 1,111,998 个。
String 字符串
在 Python 2 中,字符串以字节表示,而不是 Unicode。Python 提供了不同类型的字符串,例如 Unicode 字符串、原始字符串等。在这种情况下,如果我们想声明一个 Unicode 字符串,我们为字符串文字添加 u 前缀。
s = 'Café' # byte string
s
'Caf\xc3\xa9'
type(s)
<type 'str'>
u = u'Café' # unicode string
u
u'Caf\xe9'
type(u)
<type 'unicode'>
在 Python 3 中,字符串用 Unicode 表示。如果我们想表示字节字符串,我们为字符串文字添加 b 前缀。请注意,早期的 Python 版本(3.0-3.2)不支持 u 前缀。为了减轻从 Python 2 迁移 Unicode 感知应用程序的痛苦,Python 3.3 再次支持字符串文字的 u 前缀。
s = 'Café'
type(s)
<class 'str'>
s
'Café'
s.encode('utf-8')
b'Caf\xc3\xa9'
s.encode('utf-8').decode('utf-8')
'Café'
Characters 字符
Python 2 将所有字符串字符作为字节。在这种情况下,字符串的长度可能不等于字符的数量。例如,Café 的长度是 5,而不是 4,因为 é 被编码为 2 字节的字符。
s= 'Café'
print([_c for _c in s])
['C', 'a', 'f', '\xc3', '\xa9']
len(s)
5
s = u'Café'
print([_c for _c in s])
[u'C', u'a', u'f', u'\xe9']
len(s)
4
Python 3 将所有字符串字符视为 Unicode 码点。字符串的长度始终等同于字符的数量。
s = 'Café'
print([_c for _c in s])
['C', 'a', 'f', 'é']
len(s)
4
bs = bytes(s, encoding='utf-8')
print(bs)
b'Caf\xc3\xa9'
len(bs)
5
移植 unicode(s, ‘utf-8’)
unicode()内置函数在 Python 3 中被删除,那么转换表达式 unicode(s,'utf-8')的最佳兼容方法是什么?可以在Python2和Python3中通用呢?
# python2 版本
s = 'Café'
unicode(s, 'utf-8')
u'Caf\xe9'
s.decode('utf-8')
u'Caf\xe9'
unicode(s, 'utf-8') == s.decode('utf-8')
True
# python3 版本
s = 'Café'
s.decode('utf-8')
AttributeError: 'str' object has no attribute 'decode'
以上栗子可以看到decode()不能对Unicode编码的字符串进行反编码。
ord函数
ord 是一个强大的内置函数,它用于返回给定字符的Unicode数值,即该字符在Unicode表中的位置。
s = u'Café'
for _c in s: print('U+%04x' % ord(_c))
U+0043
U+0061
U+0066
U+00e9
u = '中文'
for _c in u: print('U+%04x' % ord(_c))
U+4e2d
U+6587
Encoding 编码
Unicode 字符串转换为Byte字节即为encoding编码。
s = u'Café'
type(s.encode('utf-8'))
<class 'bytes'>
相反,如果Byte字节转为Unicode字符为decoding反编码。
s = bytes('Café', encoding='utf-8')
s.decode('utf-8')
'Café'
当Byte字节字符串无法解码为 Unicode 字符串时,Python 会引发 UnicodeDecodeError的异常。如果我们想避免这个异常,我们可以在解码中传递替换、反斜杠替换或忽略错误的参数。
u = b"\xff"
u.decode('utf-8', 'strict')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
# use U+FFFD, REPLACEMENT CHARACTER
u.decode('utf-8', "replace")
'\ufffd'
# inserts a \xNN escape sequence
u.decode('utf-8', "backslashreplace")
'\\xff'
# leave the character out of the Unicode result
u.decode('utf-8', "ignore")
''
定义长字符串
以下是定义多行长字符串的几种方法。
# 普通单引号
s = 'This is a very very very long python string'
# 反斜杠末尾断行
s = "This is a very very very " \
"long python string"
# 使用小括号
s = (
"This is a very very very "
"long python string"
)
# 使用+号连接
s = (
"This is a very very very " +
"long python string"
)
# 使用三引号加反斜杠
s = '''This is a very very very \
long python string'''
学废了嘛,如有错误,请指正,感谢。