4. 字符串

4.1. 脚本 [str_01]:字符串表示法
脚本 [str_01] 如下:
注释
- 第 3 行:由双引号 " 分隔的字符串;
- 第 4 行:由单引号 ' 限定的字符串;
- 第 5 行:由三个引号 """ 包围的字符串。在这种情况下,字符串可以跨多行;
结果如下:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_01.py
chaine1=[un], chaine2=[deux], chaine3=[hélène va au
marché acheter des légumes]
Process finished with exit code 0
4.2. 脚本 [str_02]:<str> 类的的方法
脚本 [str_02] 展示了 <str> 类(即字符串类)的若干方法:
结合注释和所得结果,足以理解该脚本。结果如下:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_02.py
'ABCD'.lower()=abcd
'abcd'.upper()=ABCD
'cheval[2]=e
'caractères accentués'[5:7]=tè
'caractères accentués'[4:]=ctères accentués
'caractères accentués'[:5]=carac
len('123')=3
' abcd '.strip()=[abcd]
' abcd '.rstrip()=[ abcd]
' abcd '.lstrip()=[abcd ]
str.strip()=[abcd]
'abcd'.replace('a','x')=xbcd
'abcd'.replace('ab','xy')=xycd
'abcd'.find('bc')=1
'abcd'.find('bc')=-1
'abcd'.startswith('ab')=True
'abcd'.startswith('x')=False
'abcd'.endswith('cd')=True
'abcd'.endswith('x')=False
'[X]'.join(['abcd', '123', 'èéà'])=abcd[X]123[X]èéà
''.join(['abcd', '123', 'èéà'])=abcd123èéà
'abcd 123 cdXY'.split('cd')=['ab', ' 123 ', 'XY']
'abcd 123 cdXY'.split(None)=['abcd', '123', 'cdXY']
Process finished with exit code 0
4.3. 脚本 [str_03]:字符串编码 (1)
脚本 [str_03] 介绍了与字符串编码相关的概念:
对 <str> 类型的字符串进行编码会生成一个二进制字符串,其中字符串中的每个字符由一个或多个字节表示。编码类型多种多样。上面的脚本展示了西方最常见的两种编码:“utf-8”和“iso-8859-1”,后者也称为“latin1”。
编码/解码的原理如下所示(参考 |https://realpython.com/python-encodings-guide/ |):

评论
- 第4-5行:待编码的初始字符串。<str>类型的实例是Unicode字符串 |https://docs.python.org/3/howto/unicode.html|, |https://realpython.com/python-encodings-guide/ |;
- 第 6-11 行:将字符串编码为 UTF-8 的两种方法:
- 第 8 行:str.encode('utf-8');
- 第 10 行:bytes(str, 'utf-8');
- 第 12-17 行:我们对 'iso-8859-1' 编码执行同样的操作;
- 第 18-23 行:'latin1' 是 'iso-8859-1' 编码的另一个名称;
结果如下:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_03.py
str=[hélène va au marché acheter des légumes, type=<class 'str'>
--- utf-8
bytes1=b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes', type=<class 'bytes'>
bytes2=b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes', type=<class 'bytes'>
--- iso-8859-1
bytes1=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
bytes2=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
--- latin1
bytes1=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
bytes2=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
Process finished with exit code 0
注释
- 第 4 行:我们可以看到,带重音的字符使用两个字节进行编码:
- é: [\xc3\xa9],即二进制序列 11000011 10101001;
- è: [\xc3\xa8],即二进制序列 11000011 10101000;
- 第7行:在ISO-8859-1编码中,这两个带重音的字符采用不同的编码方式:
- é: [\xe9],二进制序列为 11101001;
- è: [\xe8],即二进制序列 11101000;
4.4. 脚本 [str_04]:字符串编码(2)
脚本 [str_04] 介绍了另外两种编码类型:“base64”和“quoted-printable”。这两种编码并非对 Unicode 字符串进行编码,而是对二进制对象进行编码。例如,当您将 Word 文档作为附件添加到电子邮件中时,根据所使用的电子邮件客户端不同,该文档将采用这两种编码中的一种。大多数附件文件都是如此。
脚本如下:
注释
- 第 2 行:[codecs] 模块支持 'base64' 和 'quoted-printable' 编码。它还可以处理许多其他编码;
- 第 4–7 行:将进行各种编码处理的 Unicode 字符串;
- 第 9–12 行:UTF-8 编码。这会生成一个二进制字符串;
- 第 14–18 行:进行 UTF-8 解码以恢复为原始的 Unicode 字符串;
- 第 20–29 行:我们对 'iso-8859-1' 编码重复相同的处理过程;
- 第31–34行:显示解码错误:
- 第 33 行:bytes1 是一个以 'utf-8' 编码的二进制字符串。我们将它解码为 'iso-8859-1';
- 第 36–39 行:使用 [codecs] 模块将字符串编码为 UTF-8 的另一种方法;
- 第 41–44 行:将 'utf-8' 二进制字符串编码为 'base64';
- 第 46–49 行:演示如何将 'base64' 二进制字符串转换回原始的 Unicode 字符串;
- 第 51–59 行:我们重复此过程,但使用 'quoted-printable' 编码代替 'base64';
结果如下:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_04.py
---- chaîne unicode
str1=[hélène va au marché acheter des légumes], type(str1)=<class 'str'>
---- chaîne unicode -> binaire utf-8
bytes1=[b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes'], type(bytes1)=<class 'bytes'>
---- binaire utf-8 -> chaîne unicode
str2=[hélène va au marché acheter des légumes], type(str2)=<class 'str'>
str2==str1=True
---- chaîne unicode -> binaire iso-8859-1
bytes2=[b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes'], type(bytes2)=<class 'bytes'>
---- binaire iso-8859-1 -> chaîne unicode
str3=[hélène va au marché acheter des légumes], type(str3)=<class 'str'>
str3==str1=True
--- binaire utf-8 (décodage iso-8859-1) --> chaîne unicode
str4=[hélène va au marché acheter des légumes], type(str4)=<class 'str'>
---- chaîne unicode -> binaire utf-8
bytes3=[b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes'], type(bytes3)=<class 'bytes'>
---- binaire utf-8 -> binaire base64
bytes4=[b'aMOpbMOobmUgdmEgYXUgbWFyY2jDqSBhY2hldGVyIGRlcyBsw6lndW1lcw==\n'], type(bytes4)=<class 'bytes'>
---- binaire base64 -> binaire utf-8 -> chaîne unicode
str6=[hélène va au marché acheter des légumes], type(str6)=<class 'str'>
---- binaire utf-8 -> binaire quoted-printable
str7=[b'h=C3=A9l=C3=A8ne=20va=20au=20march=C3=A9=20acheter=20des=20l=C3=A9gumes'], type(str7)=<class 'bytes'>
---- binaire quoted-printable -> binaire utf-8 -> chaîne unicode
str8=[hélène va au marché acheter des légumes], type(str8)=<class 'str'>
Process finished with exit code 0
- 第 14-15 行:使用错误的解码器 'iso-8859-1' 将 UTF-8 二进制数据解码为 Unicode 字符串。因此,生成的部分 Unicode 字符不正确,本例中为带重音的字符;
- 第 18-19 行:'base64' 编码是利用 64 个 ASCII 字符(以 7 位编码)来编码任何二进制数据。如我们所见,这会增加字符串中二进制数据的大小;
- 第22–23行:'quoted-printable'编码同样使用ASCII字符(7位编码)来编码任何二进制数据;
需要牢记的是,当接收代表文本的二进制数据(例如来自互联网)时,必须了解其经过的编码方式,才能还原原始文本。