一切内容都是摘抄,主要是便于回忆和鼓励自己不要间断,更详细内容请见原帖地址:
《深入 python3 》中文版
http://woodpecker.org.cn/diveintopython3/index.html
4.1. 在开始之前需要掌握的一些知识
实际上,从屏幕上的每一块文本都是以某种字符编码(character encoding)的方式保存的。粗略地说就是,字符编码提供一种映射,使屏幕上显示的内容和内存、磁盘内存储的内容对应起来。
4.2. Unicode
Unicode编码系统为表达任意语言的任意字符而设计。它使用4字节的数字来表达每个字母、符号,或者表意文字(ideograph)。每个数字代表唯一的至少在某种语言中使用的符号。(并不是所有的数字都用上了,但是总数已经超过了65535,所以2个字节的数字是不够用的。)被几种语言共用的字符通常使用相同的数字来编码,除非存在一个在理的语源学(etymological)理由使不这样做。不考虑这种情况的话,每个字符对应一个数字,每个数字对应一个字符。即不存在二义性。不再需要记录“模式”了。U+0041总是代表'A',即使这种语言没有'A'这个字符。
4.3. 概述
Python字符串可以通过单引号(')或者双引号(")来定义。
4.4. 格式化字符串
return '{0:.1f} {1}'.format(size, suffix)
Python 3支持把值格式化(format)成字符串。可以有非常复杂的表达式,最基本的用法是使用单个占位符(placeholder)将一个值插入字符串。
"{0}'s password is {1}".format(username, password)
这里包含了很多知识。首先,这里使用了一个字符串字面值的方法调用。字符串也是对象,对象则有其方法。其次,整个表达式返回一个字符串。最后,{0}和{1} 叫做替换字段(replacement field),他们会被传递给format()方法的参数替换。
4.4.1. 复合字段名
这个例子说明格式说明符可以通过利用(类似)Python的语法访问到对象的元素或属性。这就叫做复合字段名(compound field names)。
'1MB = 1000{0.modules[humansize].SUFFIXES[1000][0]}'.format(sys)
sys.modules是一个保存当前Python实例中所有已经导入模块的字典。模块的名字作为字典的键;模块自身则是键所对应的值。所以{0.modules}指代保存当前己被导入模块的字典。
sys.modules['humansize']即刚才导入的humansize模块。所以替换域{0.modules[humansize]}指代humansize模块。请注意以上两句在语法上轻微的不同。在实际的Python代码中,字典sys.modules的键是字符串类型的;为了引用它们,我们需要在模块名周围放上引号(比如 'humansize')。但是在使用替换域的时候,我们在省略了字典的键名周围的引号(比如 humansize)。
4.4.2. 格式说明符
{1}会被传递给format()方法的第二个参数替换,即suffix。但是{0:.1f}是什么意思呢?它其实包含了两方面的内容:{0}你已经能理解,:.1f则不一定了。第二部分(包括冒号及其后边的部分)即格式说明符(format specifier),它进一步定义了被替换的变量应该如何被格式化。
格式说明符的允许你使用各种各种实用的方法来修饰被替换的文本,就像C语言中的printf()函数一样。我们可以添加使用零填充(zero-padding),衬距(space-padding),对齐字符串(align strings),控制10进制数输出精度,甚至将数字转换成16进制数输出。
在替换域中,冒号(:)标示格式说明符的开始。“.1”的意思是四舍五入到保留一们小数点。“f”的意思是定点数(与指数标记法或者其他10进制数表示方法相对应)。因此,如果给定size为698.24,suffix为'GB',那么格式化后的字符串将是'698.2 GB',因为698.24被四舍五入到一位小数表示,然后后缀'GB'再被追加到这个串最后。
4.5. 其他常用字符串方法
splitlines()方法以多行字符串作为输入,返回一个由字符串组成的列表,列表的元素即原来的单行字符串。请注意,每行行末的回车符没有被包括进去。
lower()方法把整个字符串转换成小写的。
count()方法对串中的指定的子串进行计数。是的,在那一句中确实出现了6个字母“f”。
split()方法使用一个参数,即指定的分隔符,然后根据这个分隔符将串分离成一个字符串列表。此处,分隔符即字符“&”,它还可以是其他的内容。
最后,通过调用dict()函数Python会把那个包含列表的列表(list-of-lists)转换成字典对象。
如果需要处理URL请求参数,我们最好使用urllib.parse.parse_qs()函数,它可以处理一些不常见的边缘情况。
4.5.1. 字符串的分片
定义一个字符串以后,我们可以截取其中的任意部分形成新串。这种操作被称作字符串的分片(slice)。字符串分片跟列表的分片(slicing lists)原理是一样的,从直观上也说得通,因为字符串本身就是一些字符序列。
4.6. String vs. Bytes
字节即字节;字符是一种抽象。一个不可变(immutable)的Unicode编码的字符序列叫做string。一串由0到255之间的数字组成的序列叫做bytes对象。
by = b'abcd/x65'
使用“byte字面值”语法b''来定义bytes对象。byte字面值里的每个字节可以是ASCII字符或者是从/x00到/xff编码了的16进制数。
bytes对象是不可变的;我们不可以给单个字节赋上新值。如果需要改变某个字节,可以组合使用字符串的切片和连接操作(效果跟字符串是一样的),或者我们也可以将bytes对象转换为bytearray对象。
barr = bytearray(by)
s.count(by.decode('ascii'))
这一行代码刚好给我们演示了使用特定编码方式将bytes对象转换成字符串后该串的出现次数。
所以,这就是字符串与字节数组之间的联系了:bytes对象有一个decode()方法,它使用某种字符编码作为参数,然后依照这种编码方式将bytes对象转换为字符串,对应地,字符串有一个encode()方法,它也使用某种字符编码作为参数,然后依照它将串转换为bytes对象。
by = a_string.encode('utf-8')
by是一个bytes对象。它有13个字节。它是通过a_string使用UTF-8编码而得到的一串字节序列。
4.7. 补充内容:Python源码的编码方式
Python 3会假定我们的源码 — 即.py文件 — 使用的是UTF-8编码方式。
Python 2里,.py文件默认的编码方式为ASCII。Python 3的源码的默认编码方式为UTF-8
如果想使用一种不同的编码方式来保存Python代码,我们可以在每个文件的第一行放置编码声明(encoding declaration)。以下声明定义.py文件使用windows-1252编码方式:
# -*- coding: windows-1252 -*-
从技术上说,字符编码的重载声明也可以放在第二行,如果第一行被类UNIX系统中的hash-bang命令占用了。
#!/usr/bin/python3
# -*- coding: windows-1252 -*-