Python高效开发实战:Django、Tornado、Flask、Twisted(第3版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.2 数据类型

经过对1.1节的学习,读者已经对Python开发有所了解,从本节开始,我们将逐步学习Python的编程技巧。

数据类型的定义是一个值的集合及定义在这个集合上的一组操作。变量用来存储值的所在之处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。Python在声明变量时虽然无须指定数据类型,但是每个变量在被赋值时便会被赋予一种数据类型。所以,所有变量都具有数据类型,掌握数据类型是学好Python的基础。

1.2.1 Number类型

Number类型即数值类型,通常用于存储数字,是最常用的变量类型。

1. 类型定义

Python中的数值类型包括integer、bool、float和complex。

(1)integer:整型,相当于C语言中的int及long型。与C语言及Python 2不同的是,在Python 3中不限制整型变量的取值范围,即可以使用超出-264~264范围的数值,示例如下:

(2)bool:布尔型,多用于判断场景,只有两个值,即True和False,示例如下:

(3)float:浮点数,可以用直接的十进制或科学计数法表示,每个浮点数占8字节。浮点数值通常都有一个小数点和一个可选的后缀e(大写或小写,表示科学计数法),在e和指数之间可以用正(+)或负(-)表示指数的正负,示例如下:

其中float("inf")与float("nan")常被用来与其他数值做比较运算。

(4)complex:复数,可以指不实的数字或并非表明具体数量的数字。复数由实数部分和虚数部分构成,虚数部分必须有后缀j或J。示例如下:

2. 操作符

Python中的数值操作符分两类:一类是算术操作符,如加、减、乘、除;另一类是比特操作符,如取反、异或等。表1.1列出了Python中的算术操作符及其含义,表1.2列出了Python中的比特操作符及其含义。

表1.1 Python中的算术操作符及其含义

算术操作符的使用示例如下:

表1.2 Python中的比特操作符及其含义

比特操作符的使用示例如下:

技巧:进行比特运算时,可以先想想这些数字的二进制形式,之后就能手到擒来。比如对于表达式3 ^ 1,其二进制形式为011 ^ 001 = 010,结果为十进制的2。

3. 内置函数

除了操作符,Python中还有一组内置函数支持数值类型的变量操作。本书把这些内置函数分为两类:一类是通用函数,它们不仅适用于数值类型的变量,还适用于其他类型的变量;另一类是特定函数,它们只适用于数值类型的变量的相关操作。表1.3列出了Python中的通用函数及其含义。

表1.3 Python中的通用函数及其含义

通用函数的使用示例如下:

表1.4列出了Python中的数值类型的特定函数及其含义。

表1.4 Python中的数值类型的特定函数及其含义

数值类型特定函数的使用示例如下:

1.2.2 Sequence类型

除了基本的数值类型,Python中的Sequence类型在Python编程中占有重要的地位,Python中的字符串(string)、元组(tuple)、列表(list)都属于Sequence类型,即序列类型。可以将字符串看作由字符组成的序列类型,元组是由任意对象组成的不可修改序列类型,列表是由任意对象组成的可修改序列类型。序列类型的操作方式在这些类型中共用,本节学习序列类型的共同技巧。

1. 操作符

Python中的序列操作符包括元素提取、序列链接等,如表1.5所示。

表1.5 序列操作符及其含义

【示例1-2】序列操作符的使用示例如下:

2. 内置函数

序列类型可以使用内置函数进行求长度、类型转换、排序等操作。序列类型内置函数及其含义如表1.6所示。

表1.6 序列类型内置函数及其含义

【示例1-3】序列类型内置函数的使用示例如下:

1.2.3 string与bytes

string(字符串)是由零个或多个字符组成的有限序列。字符串通常以串的整体作为操作对象,例如,在字符串中查找某个子串、求取一个子串、在串的某个位置上插入一个子串及删除一个子串等。Python中的字符串是Sequence类型的一员,字符串用引号包含标识,如"Hello"、'This is fantacy!'。

技巧:在Python中双引号和单引号的意义相同,都可用于表示字符串。

在Python 3中,string类型中的每个字符都以Unicode方式编码,因此实际上每个字符都可由多个字节组成。与string类型相对的另一种Sequence类型是bytes(字节串),它由若干字节组成,以字节为单位进行操作。字节串用前缀b表示,如b"I’m bytes"、 b'Python3'。

string与bytes类型的对象可以通过encode()与decode()函数相互转换,比如:

在Python 3中对string类型进行这样的定义大大改善了在Python 2中恼人的非ANSI字符显示乱码的问题。总的来说,string是适用场景更多的文本Sequence类型,是本节讲解的重点。但在本书将要学习的网络通信类框架Tornado与Twisted中,收发数据的数据类型多为bytes,届时请读者注意。

1. 基本使用

Python中的字符串可以用单引号、双引号或三重引号定义,其中前两者用于定义单行文本,而三重引号用来定义多行文本。此外,在Python 2中用为字符串增加前缀u的方式将其定义为Unicode编码;但如前所述,在Python 3中所有字符串都是Unicode编码的,因此在开发过程中该前缀已无实际意义。

【示例1-4】字符串基本使用演示如下:

注意:Python 3仍然支持字符串前缀u,但其目的仅仅是兼容旧的Python 2代码。

【示例1-5】通过所有Sequence类型通用的切片操作可以读取字符串的部分内容:

【示例1-6】字符串是不可变类型,也就是说,改变一个字符串的元素需要新建一个新的字符串。如下代码演示了如何修改字符串:

技巧:因为string是一种Sequence类型,所以1.1.2中的所有操作符和函数都适用于string类型,本节不再重复举例。

2. 字符串格式化

【示例1-7】字符串格式化是按指定的规则连接、替换字符串并返回新的符合要求的字符串。比如:

Python中格式化字符串的表达式语法主要有两类:

其中format_v2是Python 2风格的格式化模板,format_v3是Python 3风格的格式化模板。格式化模板中包括字符串中的固定内容与待替换内容,待替换的内容用格式化符号标明;obj_to_convert为要格式化的字符串,如果是两个以上,则需要用小括号括起来。format_v2与format_v3中的可用格式化符号如表1.7所示。

表1.7 format_v2与format_v3中的可用格式化符号

除了表1.7中的格式化符号,有时需要调整格式化符号的显示方法,如调整数字的显示精度及是否输出正值符号“+”等,表1.8列出了辅助格式化符号的使用方法。

表1.8 辅助格式化符号的使用方法

【示例1-8】结合表1.7和表1.8,格式化字符串的使用方法举例如下:

使用Python 3风格格式化的一个好处是,可以在格式化模板中指定待替换内容的具体位置,并允许内容复用。比如:

本例中.format()的参数列表里共有两个变量,但是在格式化模板中有三个格式化符号,其中{1:s}与{1!r}替换的是同一个参数"Henry"。

此外,Python 3风格的格式化模板还允许省略替换格式,比如:

在格式化模板中用简单的花括号对“{}”就完成了内容替换。

注意:Python 2风格的字符串格式化在今后的Python版本中可能被废弃,建议在新项目开发中使用Python 3风格。

格式化字符串中的固定内容除了字母、数字、标点符号等可显示的字符,还可以包含不可显示字符,如回车、缩进等。Python中称这种字符为转义字符,表1.9总结了转义字符。

表1.9 转义字符

【示例1-9】在字符串中,这些转义字符串会被解释为相应的意义,如果在字符串前面加了标识“r”,则可禁用转义字符解释,示例如下:

3. 内置函数

字符串作为最重要的常用类型之一,有一系列特有的内置函数,常用的字符串如下。

• capitalize():将字符串中的第1个字符大写。

• center(width):返回一个长度至少为width的字符串,并使原字符串的内容居中。

• count(str,beg=0,end=len(str)):返回子串str出现的次数,可以用开始索引(beg)和结束索引(end)指定搜索的范围。

• encode(encoding='UTF-8',errors='strict'):以encoding指定的编码格式编码string,返回一个bytes类型对象。

• endswith(obj, beg=0,end=len(string))b,e:检查字符串是否以obj结束,如果是,则返回True,否则返回False;可以用开始索引(beg)和结束索引(end)指定搜索的范围。

• expandtabs(tabsize=8):把字符串string中的Tab符号转为空格,默认的空格数tabsize是8。

• find(str, beg=0,end=len(string)):检测str是否包含在string中;可以用开始索引(beg)和结束索引(end)指定搜索的范围,找到则返回索引值,找不到则返回-1。

• index(str, beg=0,end=len(string)):跟find()类似,但是如果str不在string中,则报一个异常。

• isalnum():如果发现有一个字符并且所有字符都是字母或数字,则返回True,否则返回False。

• isalpha():如果发现有一个字符并且所有字符都是字母,则返回True,否则返回False。

• isdecimal():如果可解释为十进制数字,则返回True,否则返回False。

• isdigit():如果可解释为数字,则返回True,否则返回False。

• islower():如果字符串中的字符都是小写,则返回True,否则返回False。

• isnumeric():如果只包含数字字符,则返回True,否则返回False。

• isspace():如果字符串是空格,则返回True,否则返回False。

• istitle():如果字符串是标题,则返回True,否则返回False。

• isupper():如果字符串中的字符都是大写的,则返回True,否则返回False。

• ljust(width):返回一个原字符串左对齐,并使用空格填充至长度width的新字符串。

• lower():转换所有大写字符为小写。

• lstrip():截掉string左边的空格。

• replace(str1, str2,num=count(str1)):把string中的str1替换成str2,num指定替换的最大次数。

• rfind(str, beg=0,end=len(string)):类似于find(),但是从右边开始查找。

• rindex( str, beg=0,end=len(string)):类似于index(),但是从右边开始查找。

• rjust(width):返回一个原字符串右对齐并使用空格填充至长度width的新字符串。

• rpartition(str)e:类似于partition()函数,但是从右边开始查找。

• rstrip():删除string字符串末尾的空格。

• split(str="", num=count(str)):以str为分隔符切片string,如果num有指定的值,则仅分隔num个子字符串。

• splitlines(num=count('\n')):按照行分隔,返回一个包含各行作为元素的列表,如果num已指定,则仅切片num个行。

• startswith(obj, beg=0,end=len(string)):检查字符串是否以obj开头,如果是则返回True,否则返回False。可以用开始索引(beg)和结束索引(end)指定搜索的范围。

• strip([obj]):在string上执行lstrip()和rstrip()。

• swapcase():翻转string中的大小写。

• title():将字符串标题化,即所有单词都以大写开始,其余字母均小写。

• translate(str, del=""):根据str给出的表转换string的字符,将要过滤掉的字符放到del参数中。

• upper():转换string中的小写字母为大写。

• zfill(width):返回长度为width的字符串,原字符串string右对齐,前面填充0。

【示例1-10】内置函数示例如下:

1.2.4 tuple类型

tuple类型即元组,是一种特殊的Sequence类型。tuple用圆括号“( )”表示,在不同的元素之间以逗号隔开。在Python中,tuple的大小和其中的元素在初始化后不能修改,tuple的操作速度比可修改的list的操作速度快。如果开发者定义了一个值的常量集,并且唯一要用它做的是不断地读取,则这正可以发挥tuple的长处。

【示例1-11】tuple通过Sequence类型的通用方法进行操作,示例如下:

1.2.5 list类型

list类型即列表,是一种常用的Sequence类型。list用中括号“[ ]”表示,不同的元素之间以逗号隔开。在Python中,list的大小和其中的元素在初始化后可以被再次修改,这是list与tuple的主要区别。如果开发者定义了一组值,并且在之后需要不断对其进行增、删、改等操作,则应该使用list类型。

1. 基本操作

【示例1-12】list通过Sequence类型的通用方法进行操作,示例如下:

2.内置函数

除了Sequence类型公用的操作,tuple类型还有一组自己的函数,常用的函数如下。

• append(obj):在列表尾部添加一个对象。

• count(obj):计算对象在列表中出现的次数。

• extend(seq):把序列seq的内容添加到列表中。

• index(obj, i=0, j=len(list)):计算对象obj在列表中的索引位置。

• insert(index, obj):把对象插入列表index指定的位置。

• pop(index=-1):读取并删除index位置的对象,默认为最后一个对象。

• remove(obj):从列表中删除对象obj。

• reverse():获得反向列表。

• list.sort(func=None,key=None,reverse=False):以指定的方式排序列表中的成员。

【示例1-13】这些函数的使用方式示例如下:

1.2.6 set类型

set类型即集合,用于表示相互之间无序的一组对象。集合在算术上的运算包括并集、交集、补集等。Python中的集合分为两种类型:普通集合和不可变集合。普通集合在初始化后支持并集、交集、补集等运算;而不可变集合初始化后就不能改变。

1. 类型定义

Python中通过关键字set和frozenset定义普通集合和不可变集合,初始化集合内容的方法是向其传入Sequence类型簇的变量。

【示例1-14】set类型示例如下:

普通集合定义时也可以省略set,直接用大括号“{}”代替,如:

根据集合的算术意义,Python定义了相应的操作符,如表1.10所示。

表1.10 集合操作符

【示例1-15】集合类型的操作符的使用方法如下:

2. 内置函数

set类型有一组自己的内置函数,用于集合的增、删、改等操作,如下所述。

• add():增加新元素。

• update(seq):用序列更新集合,序列的每个元素都被添加到集合中。

• remove(element):删除元素。

【示例1-16】set类型的内置函数的使用方法如下:

1.2.7 dict类型

dict类型即字典,代表一个键值存储库,工作方式很像映射表。给定一个键,可以在一个dict对象中搜索该键对应的值,因此字典被认为是键值对的列表。

1. 类型定义

dict是Python中唯一表示映射关系的类,所以其有自己独特的定义和操作方式。

【示例1-17】开发者可以用“{key1:value, key2:value…}”的方式初始化字典,示例如下:

2. 内置函数

Python为字典类型定义了丰富的函数操作,如下所述。

• clear():清除字典中的所有键值对。

• copy():复制字典的一个副本。

• fromkeys(seq,val=None):用seq中的元素作为键创建字典,所有键的值都被设为val,val默认为None。

• get(key,default=None):读取字典中的键key,返回该键的值;如果找不到该键则返回default所设的值。

• key in DICT:用in关键字判断键key在字典中是否存在,如果存在则返回True,否则返回False。

• items():返回一个包含字典中键值对元组的列表。

• keys():返回一个字典中所有键的列表。

• iteritems():返回字典中所有键值对的迭代器。

• iterkeys():返回字典中所有键的迭代器。

• itervalues():返回字典中所有值的迭代器。

• pop(key[, default]):读取某键的值,并且从字典中删除该键的值。如果键key不存在且没有设置default,则引发KeyError异常。

• setdefault(key,default=None):设置字典中键key的值为default。

• update(dict):合并字典。

• values():返回一个包含字典中所有值的列表。

【示例1-18】dict内置函数的使用方法示例如下: