第一章 初识 Python
1.1 Python 简介
1.1.1 什么是 Python
Python,发音是[ˈpaɪθɑn],本意是“蟒蛇”(这里需要说明的是,Python 并不是以蟒蛇命名,而是以电视节目 Monty Python’s Flying Circus 来命名的)。它是 1989 年由荷兰人 Guido van Rossum 发明的一种面向对象的解释型高级语言。
Python 有着简单、开发速度快、节省时间和精力的特点。
Python 本身并非所有与的特性和功能都集成到语言核心,而是被设计为可扩充。它具有丰富和强大的库,能够把用其他语言(尤其是 C++)制作的各种模块很轻松的联结在一起。为此,Python 常称为”胶水“语言。
1.1.2 Python 的版本
Python 自发布以来,主要经历三个版本的变化。
- 1994 年发布的 Python 1.0 版本(已过时)
- 2000 年发布的 Python 2.0 版本 (逐渐淘汰)
- 2008 年发布的 Python 3.0 版本(初学者首选)
Python 在版本升级时,并不是向下兼容的。
1.1.3 Python 都能做些什么
Python 作为一种功能强大,并且简单易学的编程语言而广受好评。
- Web 开发
- 大数据处理
- 人工智能
- 自动化运维开发
- 云计算
- 爬虫
- 游戏开发
以下代码将会使用 Pycharm2022.1.3 编译器以及 Python 3.7.2 版本
1.2 搭建 Python 开发环境
1.2.1 开发环境概述
1.2.2 安装 Python 解释器
第二章 Python 语言基础
2.1 Python 语法的特点
学习 Python 需要了解它的语法特点,如:注释规则、代码缩进、编码规范等。下面将对学习 Python 时首先需要了解的这些语法特点进行详细介绍。
2.1.1 注释规则
在代码中添加的标注行文字,从而帮助程序员更好的阅读代码。注释的内容将被 Python 解释器忽略,并不会在执行结果种体现出来。
在 Python 中,通常包括 3 种类型的注释,分别是:单行注释、多行注释和中文注释。
-
单行注释
语法如下:
# 注释内容 在 Python 中,使用 “#” 作为单行注释的符号。从符号“#”开始,直到换行结束,其后面所有的内容都会作为注释内容。
-
多行注释
语法如下:
''' 注释内容 ''' 或者:
""" 注释内容 """ 多行注释通常用来为 Python 文件、模块、类或者函数(方法)等添加版权、功能信息。
-
中文注释
语法如下:
# -*-coding:编码 -*- 或者:
#coding = 编码 该注释的出现主要是为了解决 Python 2.x 中不支持直接写中文的情况。虽然在 Python 3.X 中,该问题已经不复存在。但是为了规范页面的编码,也为了方便其他人及时了解文件所使用的编码,建议在文件开头加上中文注释。
2.1.2 代码缩进
Python 不像其他程序语言一样,采用大括号“{ }”分隔代码块,而是采用代码缩进和冒号 “:” 区分代码之间的层次。
例如,下面的代码中的缩进:
height = float( input( "请输入你的身高:" ) )
weight = float( input( "请输入你的体重:" ) )
bmi = weight / (height * height)
# 判断身材是否合理
if bmi < 18.5 :
print( "体重过轻" )
if bmi >= 18.5 and bmi < 24.9 :
print( "正常范围" )
if bmi >= 24.9 and bmi < 29.9 :
print( "体重过重" )
2.1.3 编码规范
-
编写规则
- 每个
import语句只导入一个模块,尽量避免一次导入多个模块; - 不要在行尾添加分号,也不要用分号将两条命令放在同一行;
- 建议每行不超过 80 个字符;
- 使用必要的空行可以增强代码的可读性;
- 通常情况下,运算符两侧、函数参数之间、逗号 “,” 两侧,建议添加空格;
- 应该避免在循环中使用 + 和 += 操作符累加字符串。这是因为字符串是不可变的,这样做会创造不必要的临时对象;
- 适当使用异常处理。
- 每个
-
命名规范
- 模块名尽量短小,并且全部使用小写字母,可以用下划线分隔多个单词;
- 模块名尽量短小,并且全部使用小写字母,不推荐使用下划线;
- 类名采用单词首字母大写形式(即 Pascal 风格)
- 模块内部的类采用下划线+Pascal 风格的类名组成;
- 函数、类的属性和方法的命名规则同模块类似;
- 常量命名时采用全部大写字母,可以使用下划线;
- 单下划线“_”开头的模块变量或者函数时受保护的,在使用 import * from 语句从模块中导入时,这些变量或者函数不能被导入。
- 使用双下划线”__“开头的实例变量或方法是类私有的。
2.2 Python 中的变量
2.2.1 保留字与标识符
-
保留字
保留字是 Python 语言中已经被赋予特定含义的一些单词,开发程序时,不可以把这些保留字作为变量、函数、类、模块和其他对象的名称来使用。
Python 中的保留的关键字可以通过以下方法查看:
import keyword keyword.kwlist -
标识符
标识符简单理解为一个名字
Python 语言的标识符命名规则如下:
- 由字母、下划线和数字组成,并且不能以数字开
- 不能使用 Python 中的保留字
| and | as | assert | break | class | continue |
|---|---|---|---|---|---|
| def | del | elif | else | except | finally |
| for | from | False | global | if | import |
| in | is | lambda | nonlocal | not | None |
| or | pass | raise | return | try | Ture |
| while | with | yield | \ | \ | \ |
2.2.2 变量
在 Python 中,严格意义上变量应该称为“名字”,也可以理解为标签。
定义变量:
- 变量名应该是一个有效的标识符
- 不能使用保留字
- 慎用小写字母 “l” 和大写字母“O”
- 应该选用有意义的单词作为变量名
语法如下:
变量名 = value
另外,Python 是一种动态语言,也就是说,变量的类型可以随时变化。
在 Python 中,使用内置函数 type()可以返回变量类型。
在 Python 中,允许多个变量指向同一个值。
在 Python 中,使用内置函数
id()可以返回变量所指的内存地址。
2.3 基本数据类型
2.3.1 数字
-
整数
-
十进制
例如以下:
1456151515151不能以 0 作为十进制数的开头( 0 除外)
-
八进制
在 Python3.X 中,对于八进制数,必须以 0o/0O 开头
-
十六进制
在 Python3.X 中,对于十六进制数,必须以 0x/0X 开头
-
二进制
-
-
浮点数
浮点数由整数部分和小数部分组成,主要用于处理包括小数的数。浮点数也可用科学计数法表示。
-
复数
Python 中的复数与数学中的复数形式完全一致,都是由实部和虚部组成。
2.3.2 字符串
字符串就是连续的字符序列,可以是计算机所能表示的一切字符集合。在 Python 中,字符串数以不可变序列,通常使用单引号、双引号或者三引号、六引号括起来。其中单引号和双引号祖父序列必须在同一行上,而三引号内的字符串可以分布在连续的多行上。
2.3.3 布尔型
2.3.3 数据类型的转换
在 Python 中,提供了以下函数进行各数据类型的转换
| 函数 | 功能 |
|---|---|
| int(x) | 将 x 转成整数类型 |
| float(x) | 将 x 转成浮点数类型 |
| complex(real ,imag) | 创建一个复数 |
| str(x) | 将 x 转成字符串 |
| repr(x) | 将 x 转成表达式字符串 |
| eval(str) | 计算 字符串中的有效 Python 表达式,并返回一个对象 |
| chr(x) | 将整数 x 转换成一个字符 |
| ord(x) | 将一个字符 x 转换为它对应的整数值 |
| hex(x) | 将一个整数 x 转换为一个十六进制字符串 |
| oct(x) | 将一个整数 x 转换为一个八进制字符串 |
2.4 基本输入和输出
2.4.1 使用 input() 函数
语法如下:
variable = input("提示文字")
在 Python 3.X 中,无论输入的是数字还是字符,都将被作为字符串读取。因此想要接收整数,需要把接受的字符串进行类型转换。语法如下:
variable =int(input("请输入整数"))
2.4.2 使用 print() 函数输出
语法如下:
print("Hello world!\n")
第三章 运算符与表达式
3.1 运算符
运算符是一些特殊的符号,主要用于数学计算、比较大小和逻辑运算等。
3.1.1 算数运算符
| 运算符 | 说明 | 实例 | 结果 |
|---|---|---|---|
| + | 加 | 12.45+16 | 28.45 |
| - | 减 | 5.231-3.21 | 2.021 |
| * | 乘 | 5*0.1 | 0.5 |
| / | 除 | 7/2 | 3.5 |
| % | 取余 | 7%2 | 1 |
| // | 取整 | 7//2 | 3 |
| ** | 幂 | 2**4 | 16 |
- 在算数操作符中使用 % 取余,如果除数是负数,那么取得的结果也是一个负值。
- 在 Python 中,除法运算,一律按照浮点数进行运算,因此两个整数相除,结果是浮点数。
注意:在使用除法、取余和取整运算时,除数不能为 0 ,否则会出现异常。
3.1.2 赋值运算符
赋值运算符主要用来为变量赋值。使用时,可以直接把等基本赋值运算符右边的值赋给左边的变量,也可以是进行某些运算后再赋值给左边。
语法如下:
variable = 1
3.1.3 比较(关系)运算符
用于对变量或表达式的结果进行大小、真假等比较。如果比较为真,则返回 Ture;如果为假,则返回 False 。
| 运算符 | 作用 | 举例 | 结果 |
|---|---|---|---|
| > | 大于 | ||
| < | 小于 | ||
| == | 等于 | ||
| != | 不等于 | ||
| >= | 大于等于 | ||
| <= | 小于等于 |
3.1.4 逻辑运算符
| 运算符 | 含义 | 用法 | 结合方向 |
|---|---|---|---|
| and | 逻辑与 | ||
| or | 逻辑或 | ||
| not | 逻辑非 |
3.1.5 位操作符
| 运算符 | 含义 | 举例 | |
|---|---|---|---|
| & | 按位与 | ||
| | | 按位或 | ||
| ^ | 按位异或 | ||
| ~ | 按位取反 | ||
| << | 左移位运算符 | ||
| >> | 右移位运算符 |
3.2 运算优先级
由高到低依次是:
| 类型 | 说明 |
|---|---|
| ** | 幂运算 |
| ~、+、- | 取反、正号和负号 |
| *、/、%、// | 算数运算符 |
| +、- | 加、减 |
| <<、>> | 左移和右移 |
| & | 按位与 |
| ^ | 按位异或 |
| | | 按位或 |
| <、<=、>、>=、!=、== | 比较运算符 |
第四章 流程控制语句
4.1 程序结构
- 顺序结构
- 选择结构
- 循环结构
4.2 选择语句
在生活中,我们总是要做出许多选择,程序也是一样。
Python 中,没有 switch 语句,因此为了实现多重选择的功能,只能使用 if……elif……else 分支语句或者 if 语句的嵌套
4.2.1 最简单的 if 语句
语法:
if 表达式:
语句块
如果只有一条语句,语句块可以直接写到冒号的右侧。但是,为了程序的可读性,建议不要这么做。
4.2.2 if……else 语句
语法如下:
if 表达式:
语句块1
else:
语句块2
在使用 else 时,else 一定不能单独使用。
4.2.3 if……elif……else 语句
语法如下:
if 表达式1:
语句块1
elif 表达式2:
语句块2
……
else:
语句块n
4.2.4 if 语句的嵌套
语法如下:
if 表达式1:
if 表达式2:
语句块1
else:
语句块2
else:
语句块3
4.3 循环语句
4.3.1 while 循环
语法如下:
while 条件表达式:
循环体
4.3.2 for 循环
语法如下:
for 迭代变量 in 对象:
循环体
-
进行数值循环
在使用 for 循环时,最基本的应用就是进行数值循环。例如,实现从 1 到 100 的累加。示例代码如下:
# coding = UTF-8 print( "计算 1 到 100 的累加\n" ) sum = 0; for i in range( 1, 101, 1 ) : sum += i print( "结果是:", sum ) ''' 计算 1 到 100 的累加 结果是:5050 ''' 其中用到
range()函数:range(start,end,step) 各参数说明如下:
- start:用于指定计数的起始值(包含该值),可以省略,默认值为 0 ;
- end:用于指定计数的结束值(不包含该值),不能省略;
- step:用于指定步长,即两个数之间的间隔,可以省略,默认值为 1 。
-
遍历字符串
使用 for 循环语句除了可以循环数值,还可以逐个遍历字符串。例如,下面的代码可以将横向显示的字符串转换为纵向显示。
# coding = UTF-8 string = "人生苦短,我用Python" print(string) for ch in string: print(ch) for 循环语句还可以用于迭代(遍历)列表、元组、集合和字典等。
4.3.3 循环嵌套
在 Python 中,允许一个循环体嵌入另一个循环,这称为循环嵌套。在 Python 中, for 循环和 while 循环都可以进行循环嵌套。
4.4 break、continue 和 pass 语句
- break:完全终止当前所有循环;
- continue:终止当前循环,进入下一次循环迭代;
- pass:表示空语句,不做任何事,一般起到占位作用。
第五章 复杂数据类型
5.1 序列
序列是一块用于存放多个值得连续内存空间,并且按一定得顺序,每个值(称为元素)都分配一个数字,称为索引或位置。通过该索引可以取出相应的值。
5.1.1 索引
序列中的每个元素都有一个编号,也称为索引(Indexing)。这个索引是从 0 开始递增的,即下标为 0 表示第一个元素,下标为 1 表示第二个元素,依次类推。
Python 比较神奇,它的索引可以是负数。这个索引从右向左计数,也就是从最后一个元素开始计数。最后一个元素的索引为 -1 ,倒数第二个元素的索引值为 -2 ,依此类推。
5.1.2 切片
切片(sliceing)操作时访问序列中元素的另一种方法,它可以访问一定范围内的元素。通过切片操作可以生成一个新的序列。
切片的语法如下:
sname[start:end:step]
参数说明:
- sname:表示被切序列的名称
- start:表示切片的开始位置(包括该位置),可以省略,默认为 0 ;
- end:表示切片的截至位置(不包括该位置),可以省略,默认为序列的长度
- step:表示切片的步长,可以省略,默认为 1 。当省略步长时,最后一个冒号也可以省略。
示例:
verse = [0,1,2,3,4,5,6,7,8,9]
print(verse[1:6]) #获取第 2 到 6 个元素
print(verse[1:6:2]) #获取第 2、4、6 个元素
如果想要复制整个序列,可以将 start 和 end 参数都省略,但是中间的冒号需要保留。
5.1.2 序列相加
在 Python 中,支持两种相同类型的序列相加(adding)操作,即将两个序列进行连接,但是不会去掉重复的元素,使用 “+” 运算符实现。
语法如下:
verse1 = [0, 1, 2, 3, 4]
verse2 = [ 5, 6, 7, 8, 9]
verse3 = verse1 + verse2
5.1.4 乘法
在 Python 中,使用整数 乘以一个序列会生成新的序列。新序列的内容为原来序列被重复 次的结果。
语法:
verse1 = [0, 1, 2, 3, 4]
verse3 = verse1 * 5
5.1.5 检查某个元素是否是序列成员
语法如下:
value in sequence
其中:
- value:表示要检查的元素
- sequence:表示指定的序列
结果:
- 该结果为一个布尔型(bool)
- 如果该元素在序列里面,就返回 Ture;反之,就返回 False。
另外,在 Python 中,也可以使用 not in 关键字实现检查某个元素是否不包含在指定的序列中。
5.1.6 对序列进行操作的函数
在 Python 中,提供了内置函数计算序列的长度、最大值和最小值。语法如下:
len() #序列的长度,即返回序列包含的元素的个数
max() #返回序列元素中的最大值
min() #返回序列元素中的最小值
除了上面介绍 3 个内置函数, Python 还提供了下表所示函数
| 函数 | 说明 |
|---|---|
| list() | 将序列转化为列表 |
| str() | 将序列转化为字符串 |
| sum() | 计算元素和 |
| sorted() | 对元素进行排序 |
| reversed() | 反向序列中的元素 |
| enumerate() | 将序列组合为一个索引序列,多用在 for 循环中 |
5.2 列表
Python 中的列表,也是由一系列按特定顺序排列的元素组成。它是 Python 中内置的可变序列。在形式上,列表所有元素都放在一对中括号中,两个相邻元素之间使用逗号分隔。在内容上,可以将整数、实数、字符串、列表、元组等任何类型的内容放入列表中,并且同一个列表中元素的类型可以不同,因为他们之间没有任何联系。
5.2.1 列表的创建和删除
-
使用赋值运算符直接创建列表
语法如下:
listname = [element1,element2,...,element n] 其中:
- listname:表示列表的名字,可以是任何符合 Python 命名规范的标识符;
- element:表示列表中的元素。
-
创建空列表
在 Python 中,可以创建空列表。语法如下:
emptylist = [] -
创建数值列表
在 Python 中,数值列表很常用。可以使用
list()函数直接将range()函数循环出来的结果转换成列表。语法如下:
list(range(11)) list(data)其中:
- data:表示可以转换成列表的数据,其类型可以是 range 对象、字符串、元组或者其他可迭代的类型的数据。
-
删除列表
对于已经创建的列表,不在使用时,可以将其删除。语法如下:
list( range( 11 ) ) del list del 在实际开发中,并不常用。因为 Python 自带的垃圾回收机制,会制动销毁不用的列表,所以即使我们不用手动将其删除, Python 也会自动将其收回。
5.2.2 访问列表元素
可以用索引来访问列表的某一个元素。例如:
listname[index]
5.2.3 遍历列表
-
直接 for 循环实现
语法如下:
for item in listname: 循环体 #输出item -
使用 for 循环和
enumerate()函数实现 语法如下:
for index,item in enumerate(listname): #输出 index 和 item 参数说明:
- index:用于保存元素的索引值
- item:用于保存获取的元素值,要输出元素内容时,直接输出该变量即可
- listname:列表的名称
5.2.4 添加、修改和删除列表元素
添加、修改和删除列表元素也称为更新列表。在实际开发时,经常需要对列表进行更新。
-
添加元素
语法如下:
listname.append(obj) 其中:
- listname:表示要添加的列表名称
- obj:要添加到列表末尾的对象
上面介绍的是向列表中添加一个元素。如果想要将一个列表中的全部元素添加到另一个列表中,可以使用列表对象的
extend()方法实现。语法如下:listname.extend(seq) 其中:
- listname:表示要添加的列表名称
- seq:要添加到列表末尾的列表
-
修改元素
修改列表中的元素只需要通过索引获取该元素,然后在为其重新赋值即可。
-
删除元素
删除元素主要由两种情况,一是根据索引删除,另一种是根据元素值进行删除。
-
根据索引删除
verse = ["长亭外", "古道边", "芳草碧连天"] del verse[-1] print( verse ) -
根据元素值删除
verse = ["长亭外", "古道边", "芳草碧连天"] verse.remove("古道边") print(verse)
-
5.2.5 对列表进行统计
-
获取指定元素出现的次数
语法如下:
listname.count(obj) 其中:
- listname:表示列表的名称
- obj:要匹配的元素
-
获取指定元素首次出现的索引
语法如下:
listname.index(obj) -
统计数值列表的元素和
语法如下:
sum(listname[,start]) 其中:
- listname:表示列表的名称
- start:表示统计开始的位置,可选参数,默认为 0 。
5.2.6 对列表进行排序
-
使用列表对象的
sort()方法实现 列表对象提供了
sort()方法对原列表中的元素进行排序。排序后原列表中的元素顺序将发生改变。语法如下:listname.sort(key = None, reverse = False) 参数说明如下:
- listname:表示要进行排序的列表
- key:表示指定一个从每个序列元素中提取一个比较键
- reverse:可选参数。如果为 Ture,则表示降序排列,如果为 False,则表示升序排列。默认为 Falses 。
-
使用内置的
sorted()函数实现 在 Python 中,提供一个内置的 sorted() 函数,用于对列表进行排序。使用该函数进行排序后,原列表的元素顺序不变,而是返回一个新的列表。sorted() 函数语法格式如下:
sorted(iterable,key=None,reverse=False) 参数说明如下:
- iterable:表示要进行排序的列表的名称
- key:表示指定一个从每个序列元素中提取一个比较键
- reverse:可选参数。如果为 Ture,则表示降序排列,如果为 False,则表示升序排列。默认为 Falses 。
5.2.7 列表推导式
使用列表推导式可以快速生成一个列表,或者根据某个列表生成满足指定需求的列表。列表推导式通常有以下几种常用的语法格式
-
生成指定范围的数值列表
list = [Expression for var in range] 参数说明:
- list:表示生成的列表名称
- Expression:表达式,用于计算新列表的元素
- var:循环变量
- range:采用 range() 函数生成的 range 对像
例如,要生成一个包含 10 个随机数的列表,要求数的范围在 10-100 之间(包括 100),具体代码如下:
import random randomnumber = [random.randint( 10, 100 ) for i in range( 10 )] print( randomnumber ) -
根据列表生成指定需求的列表
newlist = [Expression for var in list] 参数说明如下:
- newlist:表示新生成的列表名称
- Expression:表达式,用于计算新列表的元素
- var:循环变量
- list:用于生成新列表的原列表
例如,定义一个记录商品价格的列表,然后应用列表推导式,生成一个将全部商品价格打五折的列表,具体代码如下:
price = [3124, 2134, 1400, 800, 500] sale = [int( x / 2 ) for x in price] print( price ) print( sale ) -
从列表中选择符合条件的元素组成新的列表
newlist = [Expression for var in list if condition] 参数说明如下:
- newlist:表示新生成的列表名称
- Expression:表达式,用于计算新列表的元素
- var:循环变量
- list:用于生成新列表的原列表
- condition:条件表达式,用于指定筛选条件
5.2.8 二维列表
-
直接定义二列列表
例如:
list = [ [1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8,9] ] 每一行为一个一维列表,列表直接用逗号隔开。
-
使用嵌套的 for 循环创建
语法如下:
arr = [] for i in range(5): arr.append([]) for j in range(4): arr[i].append(j) -
使用列表推导式创建
语法如下:
arr = [[i for j in range(4)] for i in range(5)]如果要访问二维列表中的元素,使用索引的方式。
5.3 元组
元组(tuple)是 Python 中另一个重要的序列结构,与列表类似,也是由一系列按照特定顺序排列的元素组成。但是它是不可变序列。因此元组也称为不可变列表。在形式上,元组的所有元素都放在一对小括号内,两个相邻的元素用逗号隔开。
5.3.1 元组的创建
-
使用赋值运算符直接创建
同其他类型的 Python 语法一样,创建元组时,也可以用赋值运算符直接将一个元组赋值给变量。具体的语法如下:
tuplename = (element 1,element 2,element 3,...,element n) -
创建空元组
在 Python 中,也可以创建空元组。语法如下:
empty = () -
创建数值元组
在 Python 中,可以使用 tuple() 函数直接将 range() 函数循环出来的结果转换为数值元组。
有关 range() 函数的详细介绍,请参见 4.3.2 节
tuple()函数的用法如下:tuple(data) tuple(range) -
删除元组
对于已经创建的元组,不再使用时,可以用 del 语句将其删除。语法如下:
del tuplename
5.3.2 访问元组元素
在 Python 中,如果想要把元组的所有元素输出,可以直接使用 print() 函数。语法如下:
tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print( tuple )
或者通过元组的索引获取指定的元素。语法如下:
tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print( tuple[2] )
print( tuple[-2] )
print( tuple[0 :6 :2] ) #前两者输出的是单个元素,这个输出的是一个新的元组
另外,元组还可以使用 for 循环和 enumerate() 函数结合进行遍历。示例如下:
tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9)
for index, item in enumerate( tuple ) :
if index % 2 == 0 :
print( item, ",", end="" )
else :
print( item, "。" )
5.3.3 修改元组
元组是不可变序列,所以我们不能对它单个元素的值进行修改,但是元组也不是完全不能修改。我们可以对元组重新赋值。例如下面的代码:
tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print( tuple )
tuple = (1, 2, 3, 4, 5)
print( tuple )
另外,还可以对元组进行连接组合。例如:
tuple1 = (1, 2, 3, 4, 5, 6, 7, 8, 9)
tuple2 = (1, 2, 3, 4, 5)
print( tuple1 + tuple2 )
在进行元组连接时,连接的内容必须都是元组。不能将元组和字符串或者是列表进行连接。
5.3.4 元组推导式
使用元组推导式可以快速成成一个元组,它的表现形式和列表推导式类似,只是将列表推导式中的中括号换成小括号。例如下面代码:
import random
tuple = (random.randint( 10, 100 ) for i in range( 5 ))
print( tuple )
5.3.5 元组与列表的区别
- 列表属于可变序列,它的元素可以随时修改或删除;而元组属于不可变序列,其中的元组不可以修改,除非整体替换
- 列表可以使用 append() 、 extend() 、 insert() 、 remove() 和 pop() 等方法实现添加和修改列表元素;而元组没有这些方法,也不能删除元素
- 列表可以使用切片访问和修改列表中的元素;元组也支持切片,但是只支持切片访问元组中的元素,不支持修改
- 元组的访问和处理速度比列表快。所以如果只需要对其中的元组进行访问,而不进行任何修改,建议使用元组而不使用列表
- 列表不能作为字典的键;而元组可以
5.4 字典
字典(dictionary)和列表类似,也是可变序列,不过与列表不同 ,它是无序可变序列,保存的内容是以“键-值对”的形式存放的。类似于 Java 或者 C++ 中的 Map 对象。
字典的主要特征如下:
- 通过键而不是通过索引来读取
- 字典是任意对象的无序集合
- 字典是可变的,并且可以任意嵌套
- 字典中的键必须唯一
- 字典中的键必须不可变
5.4.1 字典的创建和删除
定义字典是,每个元素都包含两个部分:“键”和“值”,并且在“键”和“值”之间,用冒号分隔,相邻两个元素使用逗号隔开,所有元素放在一个大括号中。基本语法如下:
dictionary = {'key 1':'value 1','key 2':'value 2'}
参数说明如下:
- dictionary:表示字典的名称
- key:表示元素的键,必须是唯一的,并且不可变
- value:表示元素的值,可以是任何数据类型,不是必须唯一
铜列表和元组一样,也可以创建空字典。语法如下:
dictionary = {}
dictionary = dict()
Python 的 dicr() 方法除了可以创建一个空字典外,还可以通过已有数据快速创建字典。主要表现为以下两种形式:
-
通过映射函数创建字典
语法如下:
dictionary = dict(zip(list1,list2))参数说明如下:
- dictionary:表示字典的名称
- zip() 函数:用于将多个列表或元组对应位置的元素组合成为元组,并返回包含这些内容的 zip 对象。如果想要得到元组,可以将 zip 对象使用 tuple() 函数转换为元组;如果想要得到列表,则可以使用 list() 函数将其转换成列表
-
通过给定的键值对
dictionary = dict(key1 = value1,key2 = value2)在 Python 中,还可以使用 dict 对象的 fromkeys() 方法创建值为空的字典。语法如下:
dictionary = dict,fromkeys(list) 参数说明:
- dictionary:表示字典的名称
- list:表示作为字典的键的列表
5.4.2 访问字典
在 Python 中,如果想要将字典的全部元素输出,可以直接用 print() 函数。
dicttionary = dict( 甘雨='冰系', 胡桃="火系", 雷电将军="雷系" )
print( dicttionary )
但是,使用字典是,很少直接输出它的内容。一般根据指定的键得到相应的结果。在 python 中,访问字典元素可以通过 键 的方式实现。例如:
dicttionary = dict( 甘雨='冰系', 胡桃="火系", 雷电将军="雷系" )
print( dicttionary )
print( dicttionary["甘雨"] )
在实际开发过程中,很可能我们不知道当前存在什么键,所以避免该异常的产生。具体的解决方法是使用 if 语句对不存在的情况进行处理,即给定一个默认值。例如,可以将上面的代码修改为以下内容:
dicttionary = dict( 甘雨='冰系', 胡桃="火系", 雷电将军="雷系" )
print( dicttionary["神里凌华"] if "神里凌华" in dicttionary else "我的字典里没有此人" )
另外, Python 中推荐的方法 hi 是使用字典对象的 get() 方法获取指定键的值。语法如下:
dicttionary.get(key[,default])
参数说明如下:
- dictionary:表示当前操作的字典对象
- key:指定的键
- default:可选参数,默认为 None 。用于当指定的键不存在时,返回一个默认值。
例如,上面的代码可以写成:
dicttionary = dict( 甘雨='冰系', 胡桃="火系", 雷电将军="雷系" )
print( dicttionary.get( "雷电将军" ) )
5.4.3 遍历字典
字典是以“键-值对”的形式存储数据,素以就可能需要对这些“键-值对”进行获取。Python 提供了遍历字典的方法,通过遍历可以获取字典中的全部“键-值对”。
使用字典对象的 items() 方法可以获取字典的“键-值对”列表。语法如下:
dictionary.items()
其中,dictionary 为字典对象;返回值为可遍历的“键-值对”元组列表。
在 Python 中,字典对象还提供了 values() 和 keys() 方法,用于返回字典的“值”和“键”列表
5.4.4 添加、修改和删除字典元素
由于字典是可变序列,所以可以随时在其中添加“键-值对”,这和列表类似。向字典中添加元素的语法如下:
dictionary[key] = value
参数说明如下:
- dictionary:表示字典的名称
- key:表示要添加的元素的键,必须是唯一的,并且不可变
- value:表示元素的值,可以是任何数据类型,不是必须唯一
由于在字典中,“键”必须是唯一的,所以如果添加的新元素的“键”已经存在,则会用新元素的值替换掉旧元素的值,相当于修改字典的元素的值。
当字典中某个元素不需要时,可以使用 del 语句将其删除。例如:
dicttionary = dict( 甘雨='冰系', 胡桃="火系", 雷电将军="雷系" )
del dicttionary["甘雨"]
print( dicttionary )
当删除一个不存在的键时,将会抛出异常
5.4.5 字典推导式
使用字典推导式可以快速生成一个字典,它的表现形式和列表推导式类似。例如:
import random
dictionary = { i : random.randint( 10, 100 ) for i in range( 5 ) }
print( dictionary )
5.5 集合
Python 中的集合(set)与数学中的集合概念类似,也是用于保存不重复元素。它有可变集合和不可变集合两种。
5.5.1 创建集合
-
直接使用大括号创建
语法如下:
setname = {element 1,element 2,...} -
使用 set() 函数创建
在 Python 中,可以使用 set() 函数将列表、元组等其他可迭代对象转换为集合。 set() 函数的语法格式如下:
setname = set(iteration)
5.5.2 向集合中添加和删除元素
-
向集合中添加元素
向集合中添加元素可以使用 add() 方法实现。语法如下:
setname.add(element) -
从集合中删除元素
在 Python 中,可以使用 del 语句删除整个集合,也可以使用集合的 pop() 方法或者 remove() 方法删除一个元素,或者使用集合对象的 clear() 方法清空集合,使其变为空集合。
5.5.3 集合的交集、并集和差集运算
| 运算符 | 说明 |
|---|---|
| & | 两个集合的交集 |
| 两个集合的并集 | |
| - | 两个集合的差集 |
第六章 字符串
6.1 字符串编码转换
6.1.1 使用 encode() 方法编码
encode() 方法为 str 对象的方法,用于将字符串转化成二进制数据,也称为“编码”。语法如下:
str = "人活着就是为了樱岛麻衣!"
str.encode( encoding="utf-8" )
print( str )
//str.encode([encoding="utf-8"][,errors="strict"])
参数说明如下:
- str:表示要进行转换的字符串
- encoding="utf-8":可选参数,默认为 utf-8,用于指定进行转码时采用的字符编码
- errors="strict":可选参数,默认值为 strict,用于指定错误的处理方式。
在使用 encode() 方法时,不会修改原字符串,只是改变显示的方式。
6.1.2 使用 decode() 方法解码
decode() 方法为 bytes 对象的方法,用于将二进制数据转换为字符串,即将使用 encode() 方法转换的结果再转换为字符串,也称为“解码”。
语法如下:
bytes.decode([encoding="utf-8"][,errors="strict"])
参数说明如下:
- bytes:表示要进行转换的二进制数据
- encoding="utf-8":可选参数,默认为 utf-8,用于指定进行转码时采用的字符编码
- errors="strict":可选参数,默认值为 strict,用于指定错误的处理方式。
在使用 decode() 方法时,不会修改原字符串,只是改变显示的方式。
6.2 字符串常用操作
6.2.1 拼接字符串
使用“+”运算符可完成对多个字符串的拼接,并且返回一个新的字符串。例如,定义两个字符串,然后用“+”运算符连接,代码如下:
str1 = "人活着就是"
str2 = "为了樱岛麻衣!"
print( str1 )
print( str2 )
print( str1 + str2 )
字符串不允许直接与其他类型的数据进行拼接。
6.2.2 计算字符串的长度
由于不同的字符所占的字节数不同,所以要计算字符串长度,需要了解各字符所占的字节数。在 Python 中,数字、英文、小数点、下划线和空格占一个字节;一个汉字可能会占 2-4 个字节,占几个字节取决于采用的编码。下面以 Python 默认的 UTF-8 编码为例,即一个汉字占三个字节。
在 Python 中,提供了 len() 函数计算字符串的长度。语法如下:
len(string)
在默认情况下,通过 len() 函数计算字符串长度时,不区分英文、数字和汉字,所有字符都认为是一个。
在实际开发时,有时需要获取字符串实际所占的字节数。这时,可以通过使用 encode() 方法进行编码后,在进行获取。例如:
str = "人活着就是为了樱岛麻衣!"
print( len( str ) )
print( len( str.encode() ) )
6.2.3 截取字符串
由于字符串也属于序列,所以要截取字符串,可以采用切片的方法。通过切片的方法截取字符串的语法格式如下:
string[start:end:step]
参数说明如下:
- string:表示要截取的字符串;
- satrt:表示要截取的第一个字符索引(包括该字符),可选,默认为 0 ;
- end:表示要截取的最后一个字符的索引(不包含该字符),可选,默认为字符串的长度;
- step:表示切片的步长,可选,默认为 1 。当省略 step 时,随后一个冒号也可以省略
6.2.4 分割、合并字符串
在 Python 中,字符串对象提供了分割和合并字符串的方法。分割字符串是把字符串分割为列表,而合并字符串时把列表合并为字符串,它们可以看作是互逆操作。
-
分割字符串
字符串对象的 split() 方法可以实现字符串分割。即把一个字符串按照指定的分隔符切分为字符串列表。该列表的元素中,不包含分隔符。具体的语法如下:
str.split(sep,maxsplit) 参数说明如下:
- str:表示要进行分割的字符串
- sep:用于指定分隔符,可以包含多个字符,默认为 None ,即所用空字符(包括空格、换行、制表符等)
- maxsplit:用于指定分割的次数,可选参数。如果不指定或者为 -1 ,则分割次数没有限制,否则,返回结果列表的元素个数最多为 maxsplit+1
- 返回值:分割后的字符串列表
-
合并字符串
合并字符串与拼接字符串不同,它会将多个字符串采用固定的分隔符连接再一起。合并字符串可以使用字符串对象的 join() 方法实现。具体语法格式:
strnew = string.join(iterable) 参数说明如下:
- strnew:表示合并后的新字符串
- string:字符串类型,用于指定合并时的分隔符
- iterable:可迭代对象,该迭代对象中的所有元素(字符串)将会被合并为一个新的字符串。
6.2.5 检索字符串
在 Python 中,字符串对象提供了很多应用于字符串查找的方法。
-
count() 方法
count() 方法用于检索指定字符串在另一个字符串中出现的次数。如果检索的字符串不存在,则返回 0 ;否则返回出现的次数。其语法格式如下:
str.count(sub[,start[,end]])参数说明如下:
- str:表示原字符串
- sub:表示要检索的子字符串
- start:可选参数,表示检索范围的起始位置的索引,默认为 0 ;
- end:可选参数,表示检索范围的结束位置的索引,默认为一直检索结尾
-
find() 方法
该方法用于检索是否包含指定的子字符串。如果检索的子字符串不存在,则返回 -1 ;反之,返回首次出现该子字符串时的索引。语法如下:
str.find(sub[,start[,end]])参数说明如下:
- str:表示原字符串
- sub:表示要检索的子字符串
- start:可选参数,表示检索范围的起始位置的索引,默认为 0 ;
- end:可选参数,表示检索范围的结束位置的索引,默认为一直检索结尾
如果只想判断指定的字符串是否存在,可以使用 in 关键字实现。sub in string :如果存在,就返回 Ture;反之,返回 False 。另外也可以根据 find() 方法的返回值是否大于 -1 来确定是否存在。Python 的字符串对象还提供了
rfind()方法,从字符串右边开始查找。 -
index() 方法
index() 方法与 find() 方法类似,也是用于检索是否包含子字符串。只不过如果使用 index() 方法,当指定的字符串不存在时会抛出异常。其语法格式如下:
str.index(sub[,start[,end]]) 参数说明如下:
- str:表示原字符串
- sub:表示要检索的子字符串
- start:可选参数,表示检索范围的起始位置的索引,默认为 0 ;
- end:可选参数,表示检索范围的结束位置的索引,默认为一直检索结尾
-
startswitch() 方法
该方法用于检索字符串是否以指定子字符串开头。如果是,返回 Ture;反之,返回 False。语法格式如下:
str.startswitch(prefix[,start[,end]]) 参数说明如下:
- str:表示原字符串
- prefix:表示要检索的子字符串
- start:可选参数,表示检索范围的起始位置的索引,默认为 0 ;
- end:可选参数,表示检索范围的结束位置的索引,默认为一直检索结尾
-
endswitch() 方法
该方法用于检索字符串是否以指定子字符串结尾。如果是,返回 Ture;反之,返回 False。语法格式如下:
str.endswitch(prefix[,start[,end]]) 参数说明如下:
- str:表示原字符串
- prefix:表示要检索的子字符串
- start:可选参数,表示检索范围的起始位置的索引,默认为 0 ;
- end:可选参数,表示检索范围的结束位置的索引,默认为一直检索结尾
6.2.6 字母的大小写转换
在 Python 中,字符串对象提供了 lower() 方法和 upper() 方法进行字母的大小写转换。
-
lower() 方法
lower() 方法用于将字符串中的全部大写字母转换成小写字母。字符串长度与原字符串长度相同。语法如下:
str.lower() -
upper() 方法
用于将字符串中的全部小写字母转换成大写字母。字符串长度与原字符串长度相同。语法如下:
str.upper()
6.2.7 去除字符串中的空格和特殊字符
用户在输入数据时,可能会无意中输入多余的空格,或在一些情况下,字符串前后不允许出现空格和特殊字符,此时就需要去除字符串中的空格和特殊字符。
-
strip() 方法
该方法用于去掉字符串左、右两侧空格和特殊字符。其语法如下:
str.strip([chars]) 其中:
- str:要去除字符的字符串
- chars:可选参数,用于指定要去除的字符,可以指定多个,默认指定空格、制表符、回车符和换行符。
-
lstrip() 方法
该方法用于去掉字符串左侧的空格和特殊字符,其语法如下:
str.lstrip([chars]) 其中:
- str:要去除字符的字符串
- chars:可选参数,用于指定要去除的字符,可以指定多个,默认指定空格、制表符、回车符和换行符。
-
rstrip() 方法
该方法用于去掉字符串右侧的空格和特殊字符,其语法如下:
str.rstrip([chars]) 其中:
- str:要去除字符的字符串
- chars:可选参数,用于指定要去除的字符,可以指定多个,默认指定空格、制表符、回车符和换行符。
6.2.8 格式化字符串
格式化字符串的意思是先制定一个模板,在这个模板中预留几个位置,然后再根据需要填上相应的内容。这些空位需要通过指定的符号标记(也称为占位符),而这些符号还不会显示出来。在 Python 中,格式化字符串有两种方法。
-
使用 % 操作符
"%[-][+][0][m][.n]格式化字符"%exp参数说明如下:
- -:可选参数,用于指定左对齐,正数前方无符号,负数前方加负号
- +:可选参数,用于指定右对齐,正数前方加正号,负数前方加负号
- 0:可选参数,表示右对齐,正数前方无符号,负数前方加负号,用 0 填充数字空白处(一般与 m 参数一起使用)
- m:可选参数,表示占有宽度(或数字显示出的位数)
- .n:可选参数,表示小数点后保留的位数
- 格式化字符:用于指定字符的类型
- exp:要转换的项。如果要制定的项有多个,需要通过元组的形式进行指定,但是不能使用列表。
-
使用字符出对象的 fornat() 方法
字符串对象提供了 format() 方法用于进行字符串格式化。语法如下:
str.format(args)其中:
- str:用于指定字符串的显示样式(即模板)
下面重点介绍如何创建模板。在创建模板时,需要使用大括号和冒号指定占位符。基本语法如下:
{ [index] [ : [ [fill] align] [sign] [#] [width] [.precision] [type] ] }参数说明如下:
-
index:可选参数,用于指定要设置格式对象在参数列表中的索引位置,索引值从 0 开始,默认根据值得先后顺序自动分配
-
fill:可选参数,用于指定空白处填充得字符
-
align:可选参数,用于指定对齐方式,需要配合 width 一起使用
- <:表示内容左对齐
- > :表示内容右对齐
- =:表示内容右对齐,将符号放在填充内容的最左侧,且只对数字类型有效
- ^:表示内容居中
-
sign:可选参数,用于指定有无符号数
- +:表示正数加正号,负数加负号
- -:表示正数不变,负数加负号
- 空格:表示正数加空格,负数加负号
-
#:可选参数,对于二进制、八进制和十六进制,如果加上 # ,表示会显示 0b 0o 0x 前缀,否则不显示前缀
-
width:可选参数,用于指定所占宽度
-
.precision:可选参数,用于指定保留得小数位数
-
type:可选参数,用于指定类型
| 格式字符 | 说明 | 格式字符 | 说明 |
|---|---|---|---|
| %s | 字符串 | %r | 字符串 |
| %c | 单个字符 | %o | 八进制整数 |
| %d 或者%i | 十进制整数 | %e | 指数(基底写为 e) |
| %x | 十六进制整数 | %E | 指数(基底写为 E) |
| %f 或者%F | 浮点数 | %% | 字符% |
| 格式化字符 | 说明 | 格式化字符 | 说明 |
|---|---|---|---|
| S | 对字符串类型进行格式化 | b | 将十进制整数自动转换成二进制,再格式化 |
| D | 十进制整数 | 0 | 将十进制整数自动转换成八进制,再格式化 |
| C | 将十进制整数自动转换成对应的 Unicode 字符 | x 或者 X | 将十进制整数自动转换成十六进制,再格式化 |
| e 或者 E | 转换为科学计数法表示,再格式化 | f 或者 F | 转换为浮点数(默认小数点后保留 6 位),再格式化 |
| g 或者 G | 自动在科学计数法和浮点数中切换 | % | 显示百分比(默认显示小数点后 6 位) |
第七章 正则表达式
7.1 正则表达式语法
在处理字符串时,经常会有查找符合某些复杂规则的字符串的需求。正则表达式就是用于描述这些规则的工具。
7.1.1 行定位符
行定位符就是用来描述字符串的边界。“^”表示行的开始;“$”表示行的结尾。如:
^tm #从字符串的开头匹配tm
tm$ #从字符串的结尾匹配tm
tm #从字符串的内部匹配tm
7.1.2 元字符
常用的元字符:
| 代码 | 说明 |
|---|---|
| . | 匹配除换行符以外的任意字符 |
| \w | 匹配字母或数字或下划线或汉字 |
| \s | 匹配任意的空白符 |
| \d | 匹配数字 |
| \b | 匹配单词的开始或结束 |
| ^ | 匹配字符串的开始 |
| $ | 匹配字符串的结束 |
7.1.3 重复
使用“\w*”匹配任意数量的字母或数字。如果想匹配特定数量的字符,正则表达式为我们提供了限定符(指定数量的字符)来实现该功能。
常用的限定符如下表所示:
| 限定符 | 说明 | 举例 |
|---|---|---|
| ? | 匹配前面的字符零次或一次 | colou?r,该表达式可以匹配 colour 和 color |
| + | 匹配前面的字符一次或多次 | go+gle,该表达式可以匹配 gogle 到 go…gle |
| * | 匹配前面的字符零次或多次 | go*gle,该表达式可以匹配 ggle 到 go…gle |
| {n} | 匹配前面的字符 n 次 | go{2}gle,该表达式只匹配 google |
| {n,} | 匹配前面的字符最少 n 次 | go{2,},该表达式可以匹配 google 到 goo…gle |
| {n,m} | 匹配前面的字符最少 n 次,最多 m 次 |
7.1.4 字符类
正则表达式查找数字和字母是很简单的,因为已经有了对应这些字符集合的元字符(如:\d、\w),但是如果想要匹配没有预定义的元字符集合(比如:假名),应该怎么办?
很简单,只需要在方括号“[ ]”里列出它们就行。也可以指定一个字符范围,例如:[0-9a-zA-Z],也完全等同于 \w (只考虑英文)
想要匹配给定字符串中的任意一个汉字,可以使用[\u4e00-\u9fa5]
7.1.5 排除字符
前面几节列出的是匹配符合指定字符集合的字符串。现在反过来,匹配不符合指定字符串集合的字符串。正则表达式提供了 “^” 字符。这里放到中括号中,表示排除的意思。语法如下:
[^a-zA-Z]
该表达式用于匹配一个不是字母的字符。
7.1.6 选择字符
如何匹配身份证号码呢?身份证号码长度位 15 位或者 18 位。如果位 15 位,则全是数字;如果是 18 位,前 17 位位数字,最后一位是校验位,可能为数字或字符 X 。
在上面的描述中,包含者条件选逻辑,这就需要使用选择字符(“|”)来实现。
( ^ \d{15} $ ) | ( ^ \d{18} $ ) | ( (^ \d{17} ) ( \d | X | x) $)
7.1.7 转义字符
正则表达式中的转义字符与 Python 中的大同小异,都是将特殊字符变为普通字符。
7.1.8 分组
小括号字符的第一个作用就是可以改变限定符的作用范围。例如:
( thir | four ) th
小括号的第二个作用就是分组,也就是子表达式。
7.1.9 在 Python 中使用正则表达式语法
在 Python 中使用正则表达式时,是将其作为模式字符串使用的。例如:
"[^0-9a-z]"
"\\bm\\w*\\b"
由于模式字符串可能包括大量的特殊字符和反斜杠,所以需要写为原生字符串,即在模式字符串前加 r 或 R 。例如,上面的模式字符串采用原生字符串表示就是:
r"\bm\w*\b"
7.2 使用 re 模块实现正则表达式操作
本章节将介绍如何在 Python 中使用正则表达式。
re 模块在使用时,需要应先导入 import 语句引入,具体代码如下:
import re
7.2.1 匹配字符串
匹配字符串可以使用 re 模块的 match() 、 search() 和 findall() 方法。
- 使用
match()方法进行匹配
match() 方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回 Match 对象,否则返回 None 。其语法格式如下:
re.match(pattern,string [,flags])
参数说明如下:
-
pattern:表示模式字符串,由要匹配的正则表达式转换而来
-
string:表示要匹配的字符串
-
flags:可选参数,表示标志位,用于控制匹配方式,如:是否区分大小写等。
- 使用 search() 方法进行匹配
search() 方法用于在整个字符串中搜索第一个匹配的值,如果在起始位置匹配成功,则返回 Match 对象,否则返回 None 。语法如下:
re.search(pattern,string [,flags])
- 使用 findall() 方法进行匹配
findall() 方法用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回。如果匹配成功,则返回包含匹配结果的列表,否则返回空列表。其语法格式如下;
re.findall(pattern,string [,flags])
常用的标志如下表所示:
| 标志位 | 说明 |
|---|---|
| A 或 ASCII | 对于\w \W \b \B \d \D \s \S 只进行 ASCII 匹配(仅适用于 Python3) |
| I 或者 IGNORECASE | 执行不区分字母大小写的匹配 |
| M 或者 MULTILING | 将^和$用于包括整个字符串的开始和结尾的每一行 |
| S 或者 DOTALL | 使用“.”字符匹配所有字符,包括换行符 |
| X 或者 VERBOSE | 忽略模式字符串中未转义的空格和注释 |
7.2.2 替换字符串
sub() 方法用于实现字符串的替换。其语法如下:
re.sub(pattern,repl,string,count,flags)
参数说明如下:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来
- repl:表示要替换的字符串
- string:表示要被查找替换的原始字符串
- count:可选参数,表示模式匹配后替换的最大次数,默认值为 0 ,表示替换所有的匹配
- flags:可选参数,表示标志位,用于控制匹配方式,如:是否区分大小写等
7.2.3 使用正则表达式分割字符串
split() 方法用于实现根据正则表达式分割字符串,并以列表对的形式返回。其语法格式如下:
re.split(pattern,string [,maxsplit] [,flags])
参数说明如下:
- pattern:表示模式字符串,由要匹配的正则表达式转换而来
- string:表示要被怕匹配的字符串
- maxsplit:可选参数,表示最大的拆分次数
- flags:可选参数,表示标志位,用于控制匹配方式,如:是否区分大小写等
第八章 函数
8.1 函数的创建和调用
8.1.1 创建一个函数
创建函数也被称为定义函数。使用 def 关键字实现。具体语法如下:
def functionname([parameterlist]):
["""comments"""]
[functionbody]
参数说明如下:
- functionname:函数名称,在调用函数时使用
- parameterlist:可选参数,用于指定向函数中传递的参数。参数之间用逗号分隔
- """comments""":可选参数,表示为函数指定的注释
- functionbody:可选参数,用于指定函数体,即该函数被被调用之后,要执行的功能代码。
如果想定义一个什么也不做的空函数,可以使用 pass 语句作为占位符
8.1.2 调用函数
调用函数也就是执行函数。基本语法如下:
functionname([parametersvalue])
参数说明如下:
- functionname:函数名称,要调用的函数名称必须是已经创建好的
- parametersvalue:可选参数,用于指定各个参数的值。参数之间用逗号隔开
8.2 参数传毒
8.2.1 形式参数和实际参数
在使用函数时,经常会用到形式参数和实际参数。下面从两个角度了解这两种参数。
- 通过作用理解
- 形式参数:在定义函数时,函数名后面括号中的参数为形式参数
- 实际参数:在调用一个函数时,函数名后面的括号中的参数为实际参数
8.2.2 位置参数
位置参数也称必备参数,是必须按照正确的顺序传到函数中,即调用时的数量和位置必须和定义时是一样的。
-
数量必须与定义时一致
在调用函数时,指定的实际参数的数量必须与形式参数的数量一致,否则将会抛出 TypError 异常,提示缺少必要的位置参数
def nothing( a, b, c, d ) : pass 上面代码运行的结果为:
-
位置必须与定义时一致
在调用函数时,指定的实际参数的位置必须与形式参数的位置一致,否则将产生以下两种结果。
-
抛出 TypError 异常
实际参数的类型与形式参数的类型不符,并且在函数中,这两种类型不能正常转换。
-
产生的结果与预期不符
-
8.2.3 关键字参数
关键字参数是指使用形式参数的名字来确定输入的参数值。通过这种方式指定实际参数时,不再需要与形式参数的位置完全一致,只需要将参数名写正确即可。
例如,下面代码:
def nothing( a, b, c, d ) :
pass
nothing( a=1, b=2, c=3, d=3 )
8.2.4 为参数设置默认值
调用函数时,如果没有指定某个参数将抛出异常,为了解决这个问题,我们可以为参数设置默认值,即在定义函数时,直接指定形式参数的默认值。这样,当没有传入参数时,直接使用定义函数时设置的默认值。
定义带有默认值参数的函数的语法格式如下:
def functionname( ... [parameter 1 = value 1 , .... ] ):
[functionbody]
参数说明如下:
- functionname:函数名称
- parameter 1 = value 1:可选参数,用于指定向函数中传递的参数,并且为该参数设置默认值为 value 1
- functionbody:可选参数,用于指定函数体
在定义函数时,指定的默认的形式参数必须在所有参数的后面,否则将会产生语法错误
8.2.5 可变参数
在 Python 中,还可以定义可变参数。可变参数也称为不定长参数,即传入函数的实际参数可以是 0 个、1 个 到任意个。
-
*parameter
这种形式表示接收任意多个实际参数并将其放到一个元组中。例如:
def yuanshen( *name ) : string = "原神有:{} 角色" for item in name : print( string.format( item ), end=" " ) print( "" ) yuanshen( "胡桃" ) yuanshen( "胡桃", "雷电将军", "八重神子" ) -
parameter
这种形式表示接收任意多个类似关键字参数一样的显式赋值的实际参数,并将其放到一个字典中。
8.3 返回值
在 Python 中,可以在函数体内使用 return 语句为函数指定返回返回值,该返回值可以是任意类型,并且无论 return 语句出现在函数的什么位置,只要得到执行,会直接结束当前执行的函数。基本语法如下:
return [value]
8.4 变量的作用域
变量的作用域是指程序代码能够访问该变量的区域,如果超出该区域,在访问时就会出现错误。在程序中,一般会根据变量的有效作用范围,将变量分为局部变量和全局变量。
8.4.1 局部变量
局部变量是指在函数内部定义并使用的变量,它只在函数内部有效。
8.4.2 全局变量
与局部变量对应,全局变量能够作用于函数内外的变量。
8.5 匿名函数
匿名函数(lambda)是指没有名字的函数,应用在需要一个函数但又不想费神去命名这个函数的场合。通常情况下,这种函数只会使用一次。其语法如下:
result = lambda [arg1] : expression
第九章 面向对象程序设计
9.1 面向对象概述
面向对象(Object Oriented)的英文缩写是 OO,它是一种设计思想。从 20 世纪 60 年代提出面向对象的概念到现在,他已经发展成为一种比较成熟的编程思想,并且逐步成为目前软件开发领域的主流技术。
面向对象中的对象,通常是指客观世界中存在的对象,这个对象具有唯一性,对象之间各不相同,各有各的特点,每个对象都有自己的运动规律和内部状态;对象之间又是可以相互联系、互相作用的。另外,对象也可以是一个抽象的事物。例如,可以从圆形、正方形、三角形等图形抽象出一个简单图形,简单图形就是一个对象,它有自己的属性和行为。
9.1.1 对象
对象,表示任意存在的食物。世间万物皆对象。
通常将对象划分为两个部分,即静态部分与动态部分。静态部分被称为“属性”,任何对象都具备自身的属性,如:人的性别;动态部分只对象的行为,即对象执行的动作,如:人可以行走。
9.1.2 类
类是封装对象的属性和行为的载体,反过来说,具有统一属性的行为的一类实体被称为类。
9.1.3 面向对象程序设计的特点
面向对象程序设计具有三大基本特征:封装、继承和多态。
-
封装
封装是面向对象编程的核心思想,将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类。类通常对客户隐藏其实现细节,这就是封装的思想,简单来说,用户访问类的成员时,加以一定的访问限制。
采用封装思想,保证了类内部数据结构的完整性,使用该类的用户不能直接看到类中的数据结构,而只能执行类允许公开的数据,这样就避免了外部对内部数据的影响,提高了程序的可维护性。
-
继承
继承是实现重复利用的重要手段,子类通过继承父类的属性和行为的同时,又添加了子类特有的属性和行为。
-
多态
将父类对象应用于子类的特征就是多态。
9.2 类的定义和使用
9.2.1 定义类
在 Python 中,类的定义使用 class 关键字来实现,语法如下:
class ClassName(BaseClass):
"""类的说明信息"""
statement
参数说明:
- ClassName:用于指定类名,一般采用 Pascal 命名法
- BaseClass:继承的父类的类名,如果没有继承可不写(同时可以省略括号)
- """类的说明信息""":用于指定类的文档字符串,定义该字符串后,在创建类时,输入类名和括号,将会显示该信息
- statement:类体,包含该类的所有成员
9.2.2 创建类的实例
定义完类后,并不会真正创建一个实例。创建类的实例的语法如下:
ClassName(parameterlist)
9.2.3 创建__init__() 方法
在创建类后,通常会创建一个 __init__() 方法。该方法是一个特殊的方法,类似 Java 或 C# 的构造函数。每当创建一个类的实例化时, Python 都会自动执行它。__init__() 必须包含一个 self 参数,并且必须是第一个参数。self 参数是一个指向实例本身的引用,用于访问类中的属性和方法。在方法调用时,会自动传递实际参数 self 。因此,当__init__() 方法只有一个参数是,在创建类的实例时,就不需要指定实际参数了。
__init__() 方法的名称中,开头结尾是双下划线,这是一种约定。
9.2.4 创建类的成员并访问
在 Python 中,类的成员有三种:类属性、实例属性、实例方法。
-
创建实例方法并访问
所谓实例方法,是在类中定义的函数。实例方法的第一个参数必须是 self ,并且必须包含一个 self 参数。创建实例方法的语法如下:
def functionname(self,parameterlist): block 参数说明如下:
-
functionname:用于指定方法名,一般使用小写字母开头
-
self:必要参数,表示类的实例,其名称可以是 self 以外的单词,使用 self 只是一个习惯而已
-
parameterlist:用于指定除 self 参数以外的参数
-
block:方法体,实现的具体功能
实例方法创建完成后,可以通过类的实例名和( . )操作符进行访问。
-
-
创建数据成员并访问
-
类属性
类属性是指定义在类中,并且在类方法之外的属性。类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。
类属性可以通过类名加 “ . ” 进行访问,也可以用实例名加 “ . ” 进行访问
-
实例属性
实例属性是指定义在类的方法中的属性,只作用于当前实例。对于实例属性,可以通过实例名称修改,但是并不会影响到另一个实例中的相应的实例属性。
-
-
💰 类属性和实例属性的区别
- 在内存上,每个实例对象都会在内存中开辟一块空间,用于存储自身的实例属性,因此,实例属性之间不会相互影响;
- 类属性只会开辟一份内存空间,所有实例对象的类属性共用一块内存,因此,在实例 A 中修改类属性,会导致实例 B ….等所有当前存在的实例对象的类属性发生变化
9.2.5 self 参数的详细解读
self 有两个基本作用:
- 区别类属性和实例属性(类属性没有 self),同时区分传入类的参数与实例属性
- 占位符,表示对当前操作对象的引用
例如:
class Person :
a = 10
def __init__( self, a, b ) :
self.a = a
self.b = b
zhangsan = Person( 1, 2 )
lisi = Person(20,30)
print( Person.a )
print( zhangsan.a )
print( zhangsan.b )
-
首先,传入类的构造方法的参数 a、b,为了区分实例属性 a 和 b
-
当创建 zhangsan 时,self 将代表着 zhangsan,类中的所有 self 均可以被替换为 zhangsan(前提是当前操作的是 zhangsan 这个实例对象)
#伪代码 zhangsan = Person(a = 1,b = 2): a = 10 def __init__( zhangsan, a, b ) : zhangsan.a = a zhangsan.b = b 当创建 list 时,就是把 self 替换成 list 由此可见,self 代表着对当前对象的引用。
9.2.6 访问限制
在类的内部可以定义属性和方法,而在类的外部则可以直接调用属性或方法来操作数据,从而隐藏了类内部的复杂逻辑。但是,Python 并没有对属性和方法的访问权限进行限制。为了保护类内部的某些属性或方法不被外部访问,可以在属性或方法名前添加单下划线、双下划线或者首尾加双下划线,从而限制访问权限。
- _foo:以单下划线开头的表示 保护(protected)类型的成员,只允许该类本身和子类进行访问,但是不能使用 “ from module import * ” 语句导入
- __foo:以双下划线开头的表示 private(私有)类型的成员,只允许定义该方法的类本身进行访问,而且也不能通过类的实例进行访问,但是可以通过 “ 类的实例名.类名.__xxx ” 进行访问
- __foo__:首尾双下划线表示特殊定义方法,一般是系统定义名字,如:__init__
9.3 属性
本章节介绍的属性与前面的类属性和实例属性不同。本章节要介绍的属性是一种特殊的属性,访问它时将计算它的值。
9.3.1 创建用于计算的属性
在 Python 中,可以通过 @property(修饰器)将一个方法转换为属性,从而实现用于计算的属性。将方法转换为属性后,可直接通过方法名来访问方法,而不需要在添加一对小括号,这样可以让代码更加简洁。
语法如下:
class ClassName:
@property
def methodname(self):
block
tmp = ClassName()
print(tmp.methodname)
9.3.2 为属性添加安全保护机制
在 Python 中,默认情况下,创建的类属性或者实例属性可以在类体外进行修改,如果想要限制其不能在类体外修改,可以将其设置为私有,但是设置为私有后,在类体外也不能获取它的值。如果想要创建一个可以读取,但是不能修改的属性,那么可以使用 @property(修饰器)实现只读属性。
例如:
class YuanShen :
def __init__( self ) :
self.__company = "米哈游"
@property
def company( self ) :
return self.__company
game = YuanShen()
print( game.company )
9.4 继承
在编写类时,并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间存在一定的继承关系,就可以通过继承来达到代码重用的目的,提高开发效率。
9.4.1 继承的基本语法
继承是面向对象编程最重要的特性之一。
具体语法如下:
class ClassName(baseclasslist):
"""类的帮助信息"""
Statement
参数说明如下:
- baseclasslist:用于指定继承的父类,可以有多个。如果不指定,将使用所有 Python 对象的根类 Object 。
9.4.2 方法重写
父类的成员都会被子类继承(除了私有成员),当父类中的某个方法不完全适用于子类时,就需要在子类中重新定义这个方法,这和 Java 语言中的方法重写是一样的。
例如:
class Fruit :
color = "绿色"
def harvest( self, color ) :
print( "水果的颜色是:", color, "的!" )
class Apple( Fruit ) :
color = "红色"
def harvest( self, color ) :
print( color, "是水果的颜色" )
apple = Apple()
apple.harvest( "白色" )
9.4.3 子类调用父类的__init__() 方法
在子类中定义__init__() 方法时,不会自动调用父类的__init__() 方法。因此,要让子类调用父类的__init__() 方法进行必要的初始化,需要在子类的__init__() 方法里面使用 super() 函数调用父类的__init__() 方法。语法如下:
class Fruit :
color = "绿色"
def __init__( self ) :
print( "我是父类" )
def harvest( self, color ) :
print( "水果的颜色是:", color, "的!" )
class Apple( Fruit ) :
color = "红色"
def __init__( self ) :
print( "我是子类" )
super().__init__()
def harvest( self, color ) :
print( color, "是水果的颜色" )
apple = Apple()
第十章 模块
10.1 模块概述
在 Python 中,一个扩展名为 .py 的文件就称为一个模块。通常情况下,我们把能够实现某一特定功能的代码放置在一个文件中作为一个模块,从而方便其他程序和脚本导入并使用。另外,使用模块也可以避免函数名和变量名冲突。
10.2 自定义模块
在 Python 中,自定义模块有两个作用,意识规范代码,让代码更易阅读,另一个是方便其他程序使用已经编写好的代码,提高开发效率。自定义模块的主要分为两部分,一部分是创建模块,另一部分是导入模块。
10.2.1 创建模块
创建模块可以将模块中的相关代码编写在一个单独的文件中,并且将该文件命名为“ 模块名.py ” 的形式。
创建模块时,设置的模块名不能是 Python 自带的标准模块名称。模块文件的扩展名必须是 .py
10.2.2 导入模块
创建模块后,就可以在其他程序中使用该模块。使用模块需要先以模块的形式加载模块中的代码,这可以使用 import 语句实现。语法如下:
import modulename [as alias]
参数说明如下:
- modulename:要导入的模块的名称
- as alias:给模块起的别名,通过别名也可以使用模块
使用 import 语句还可以一次性导入多个模块,在导入多个模块时,模块名之间用逗号隔开。
在使用 import 语句导入模块时,每执行一条 import 语句,都会创建一个新的命名空间(namespace),并且在该命名空间中执行与 .py 文件相关的所有语句。所以,在执行时,需要在具体的变量、函数和类名前加上 “模块名” 前缀。如果不想再每次导入模块时都创建一个新的命名空间,而是将具体的定义导入当前的命名空间中,这时可以使用 from…import 语句。具体语法如下:
from modulename import member
from modulename import *
参数说明如下:
- modulename:要导入的模块名称
- member:用于指定导入的变量、函数或类等
- 使用星号 ✳:表示导入模块里面的全部内容
使用 import 导入模块时,模块名是区分大小写的
10.2.3 模块搜索目录
当使用 import 语句导入模块时,默认情况下,会按照以下顺序进行查找:
- 当前执行的 Python 脚本所在目录
- 到 PYTHONPATH(环境变量)下的每个目录中查找
- 到 Python 的默认安装位置目录下查找
以上各个目录的具体位置保存在标准模块 sys 的 sys.path 变量中。可以通过下面代码查看:
import sys
print( sys.path )
如果导入的模块不在 上述代码运行结果的目录 中,那么在导入模块是将会抛出异常。这时,我们可以通过以下 3 中方法添加指定的目录到 sys.path 中。
-
临时添加
import sys path = "E:/xx/xx" sys.path.append( path ) -
增加 .pth 文件(🎆 推荐用法)
在 Python 安装目录下的 Lib\site-package 子目录中,创建一个扩展名为 .pth 的文件,文件名任意。在该文件中添加要导入的模块所在目录。
#.pth 文件 E:/xx/xx创建 .pth 文件后,需要重新打开要执行导入模块的 Python 文件,否则新添加的目录不起作用。
-
在 PYTHONPATH 环境变量中添加
10.3 Python 中的包
使用模块可以避免函数名和变量名重名引发为错误。那么,模块名重复则么办呢?在 Python 中提出了包(package)的概念。包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下。这样,既可以起到规范代码的作用,又可以避免模块名重复引起的错误。
10.3.1 Python 程序的包的结构
10.3.2 创建和使用包
-
创建包
创建包实际上就是创建一个文件夹,并且在该文件夹中创建一个名为“__init__.py” 的 Python 文件。在__init__.py 文件中,可以不编写任何代码,也可以编写一些 Python 代码。在__init__.py 文件中所编写的代码,在导入包时会自动执行。
-
使用包
- 使用 “import + 完整包名 + 模块名”
- 使用 “from + 完整包名 import 模块名”
- 使用 “import + 完整包名 + 模块名 + import + 定义名”
10.3.4 以主程序的形式执行
在 Python 中,执行的脚本文件在导入模块时,会执行模块里面的代码,如果模块里面存在测试代码,如:print() 等,同样也会执行该函数。
name = "米哈游"
def add(a,b):
return a+b
print("我是测试代码!")
这显然不是我们想看到的,我们希望导入的模块的函数不会自动执行,而是我们手动去调用。因此,在模块里面,添加下列代码:
name = "米哈游"
def add(a,b):
return a+b
if __name__ == "__main__":
print("我是测试代码!")
将模块里面的测试代码放入“if __name__ == "__main__":” 里面。当模块里面的代码以主程序运行时,就会执行测试代码,而模块以库导入其他主程序时,就不会执行测试代码。
10.4 引用其他模块
在 Python 中,除了自定义的模块外,还可以引用其他模块,主要包括标准模块和第三方模块。
10.4.1 导入和使用标准模块
Python 中提供了 200 多个内置的标准模块,涵盖了 Python 运行时服务、文字模式匹配、操作系统接口、数学运算、对象永久保存、网络和 Internet 脚本和 GUI 构建等方面。可以在 Python 的帮助文档查看。
10.4.2 第三方模块的下载与安装
在进行 Python 程序开发时,除了可以使用 Python 内置的标准模块,还有很多第三方模块可以让我们使用。对于这些第三方模块,可在 Python 的官网推出的皮皮 ·Python 包索引)中可以让我们找到。
-
安装第三方模块
pip install modulename -
卸载第三方模块
pip uninstall modulename -
查看已经安装的第三方模块
pip list
第十一章 异常处理
11.1 异常概述
在程序运行过程中,经常会遇到各种错误,这些错误统称为异常。
| 异常 | 描述 |
|---|---|
| NameError | 尝试访问一个没有声明变量引发的错误 |
| IndexError | 索引超出序列范围引发的错误 |
| IndentionError | 缩进错误 |
| ValueError | 传入的值错误 |
| KeyError | 请求一个不存在的字典关键字引发的错误 |
| IOError | 输入输出错误 |
| ImpotyError | 当 import 语句无法找到模块或 from 无法在模块中找到相应的名称时引发的错误 |
| AttributeError | 尝试访问未知的对象属性引发的错误 |
| TypeError | 类型不合适引发的错误 |
| MemoryError | 内存不足 |
| ZeroDivisionError | 除数为 0 引发的错误 |
上述所示的异常,了解即可。
11.2 异常处理语句
11.2.1 try…except 语句
具体语法如下:
try:
block1
except [ExceptionName [as alias]]:
block2
参数说明如下:
- block1:表示可能出现的错误的代码块
- ExceptionName [as alias]:可选参数,用于指定要捕获的异常
- block2:表示进行异常处理的代码块
使用 try…except 语句捕获异常后,当程序出现错误时,程序会继续执行
11.2.2 try…except…else 语句
与 try…except 不同的时,在 try 语句没有发生异常的时候,就会执行 else 中的代码
11.2.3 try…except…finally 语句
完整的异常处理应该包含 finally 代码块,通常情况下,无论程序中有无异常产生, finally 代码块中的代码总会执行。
11.2.4 使用 raise 语句抛出异常
如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用 raise 语句在函数或方法中抛出异常。raise 语句的基本格式如下:
raisl [ExceptionName[(reason)]]
11.3 程序调试
第十二章 文件及目录操作
12.1 基本文件操作
在 Python 中,内置了文件(File)对象。在使用文件对象时,首先需要通过内置的 open() 方法创建一个文件对象,然后通过该对象提供的一些方法进行一些基本文件操作。
12.1.1 创建和打开文件
在 Python 中,想要操作文件需要首先创建或打开指定文件并创建文件对象,这样可以使用内置的 open() 方法实现。基本语法如下:
file = open(filename [, mode [, buffering]] )
参数说明如下:
- file:被创建的文件对象
- filename:要创建或打开的文件的名称,需要使用单引号或者双引号括起来。如果打开的文件和当前文件在同一目录下,直接使用文件名即可,否则需要制定完整的路径
- mode:可选参数,用于指定文件的打开模式
- buffering:可选参数,用于指定读写文件的缓冲模式,值为 0 表示不缓存;值为 1 表示缓存;如果大于 1 ,则表示缓冲区的大小。默认为缓存模式
| 打开模式 | 说明 | 注意 |
|---|---|---|
| r | 以只读模式打开文件。文件的指针将会放在文件的开头 | 文件必须存在 |
| rb | 以二进制格式打开文件,并且采用只读模式。文件的指针将会在文件的开头。一般用于非文本文件,如:图片、声音等 | 文件必须存在 |
| r+ | 打开文件后,可以读取文件内容,也可以写入新的内容覆盖原有内容(从文件开头进行覆盖) | 文件必须存在 |
| rb+ | 以二进制格式打开文件,并且采用读写模式。文件的指针将会在文件的开头。一般用于非文本文件,如:图片、声音等 | 文件必须存在 |
| w | 以只写模式打开文件 | 文件存在,则将其覆盖;反之,则创建新文件 |
| wb | 以二进制格式打开文件,并且采用只写模式。文件的指针将会在文件的开头。一般用于非文本文件,如:图片、声音等 | 文件存在,则将其覆盖;反之,则创建新文件 |
| w+ | 打开文件后,先清空原有内容,使其变为一个空文件,对这个空文件有读写权限 | 文件存在,则将其覆盖;反之,则创建新文件 |
| wb+ | 以二进制格式打开文件,并且采用读写模式。文件的指针将会在文件的开头。一般用于非文本文件,如:图片、声音等 | 文件存在,则将其覆盖;反之,则创建新文件 |
| a | 以追加模式打开一个文件,并且采用追加模式。如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入到已有内容之后),否则,创建新文件用于读写 | |
| ab | 以二进制模式打开一个文件,并且采用追加模式。如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入到已有内容之后),否则,创建新文件用于读写 | |
| a+ | 以读写模式打开一个文件。如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入到已有内容之后),否则,创建新文件用于读写 | |
| ab+ | 以二进制模式打开一个文件,并且采用追加模式。如果该文件已经存在,文件指针将放在文件的末尾(即新内容会被写入到已有内容之后),否则,创建新文件用于读写 |
12.1.2 关闭文件
打开文件后,需要及时关闭,以免对文件造成不必要的破坏。关闭文件可以使用 close() 方法实现。语法格式如下:
file.close()
其中:
- file:为打开的文件对象
12.1.3 打开文件时使用 with 语句
打开文件后,要将其及时关闭,,如果忘记关闭,可能会出现意想不到的问题。
with expression as target:
with - body
参数说明如下:
- expression:用于指定一个表达式
- target:用以指定一个变量,并且将 expression 结果保存到该变量中
- with - body:用于指定 with 语句体,其中可以是执行 with 语句后相关的一些操作语句。
12.1.4 写入文件
前面我们学习了如何创建文件,但是该文件没有任何内容,它的大小是 0 KB。Python 的文件对象提供了 write() 方法,可以向该文件中写入内容。语法如下:
file.write(string)
在我们写入文件后,写入的内容会先保存在缓冲区,只有当调用了 flush() 或 close() 方法后,操作系统才会把缓冲区的内容写入磁盘。
12.1.5 读取文件
-
读取指定字符
文件对象提供了 read() 方法,读取指定个数的字符。语法格式如下:
file.read([size]) 其中:
- file:为打开的文件对象
- size:为可选参数,用于指定要读取的字符个数,默认省略为读取所有内容
使用上述方法读取文件时,是从开头开始读取的。如果想要读取部分内容,可以先使用文件对象的 seek() 方法将文件指针移动到新位置,然后再用 read() 方法读取。语法如下:
file.seek( offset [, whence ] ) 参数说明如下;
- file:表示已经打开的文件
- offset:用于指定移动的字符个数,其具体位置与 whence 有关
- whence:可选参数,用于指定从什么位置开始计算。值为 0 表示从文件头部开始计算,1 表示从文件当前位置开始计算,2 表示从文件尾部开始计算,默认省略为 0
-
读取一行
在使用 read() 方法读取文件时,如果文件很大,一次读取全部内容到内存,容易造成内存不足,所以通常会采用逐行读取。语法如下:
filereadline() -
读取全部行
读取全部行的作用与 read() 方法一样,只不过读取全部行时,返回的是一个字符串列表,每个元素为文件的一行内容。其语法格式如下:
file.readlines()
12.2 目录操作
12.2.1 os 和 os.path 模块
在 Python 中,内置了 os 模块以及其子模块 os.path 用于对目录或文件进行操作。在使用 os 模块或者 os.path 模块时,需要用 import 语句进行导入。
import os
import os.path
os 模块常用的变量有:
- name:用于获取操作系统的类型
- 输出为 nt ,则代表为 Windows 操作系统
- 输出为 posix ,则表示为 Linux
- linesep:用于获取当前操作系统上的换行符
- sep:用于获取当前操作系统所使用的路径分隔符
os 模块提供的一些操作目录的函数:
| 函数 | 说明 |
|---|---|
| getcwd() | 返回当前的工作目录 |
| listdir(path) | 返回指定路径下的文件和目录信息 |
| mkdir(path[,mode]) | 创建目录 |
| makedirs(path1/path2/path3…[,mode]) | 创建多级目录 |
| rmdir(path) | 删除目录 |
| remove(path1/path2) | 删除多级目录 |
| chdir(path) | 把 path 设置为当前工作目录 |
| walk(top[,topdown[,onerror]]) | 遍历目录树,该方法返回一个元组,包括所有的路径、所有目录列表和文件列表三个元素 |
os.path 模块提供一些操作目录的函数:
| 函数 | 说明 |
|---|---|
| abspath(path) | 用于获取文件或目录的绝对路径 |
| exists(path) | 用于判断目录或文件是否存在,如果存在则返回 Ture;反之,返回 False |
| join(path,name) | 将目录与目录或文件名拼接起来 |
| splitext() | 分离文件名或扩展名 |
| basename(path) | 从一个目录中提取文件名 |
| dirname(path) | 从一个路径中提取文件,不包括文件名 |
| isdir(path) | 用于判断是否为有效路径 |
12.2.2 路径
-
相对路径
import os print(os.getcwd()) # 输出当前目录 -
绝对路径
获取某文件的绝对路径:
os.path.abspath(path) -
拼接路径
如果想要将两个或者多个路径拼接在一起,组成一个新的路径,可以使用
os.path模块的join()函数实现。具体语法如下:os.path.join(path1,path2,path3...)
12.2.3 判断目录是否存在
os.path.exists(path)
12.2.4 创建目录
-
创建一级目录
os.mkdir(path,mode=0o777)参数说明:
- path:用于指定要创建的目录,可以使用绝对路径或相对路径
- mode:用于指定数值模式,默认为 0777。该参数在非
UNIX系统上无效
-
创建多级目录
os.makedirs(name,mode=0o777)参数说明:
- name:用于指定要创建的目录,可以使用绝对路径或相对路径
- mode:用于指定数值模式,默认为 0777。该参数在非
UNIX系统上无效
12.2.5 删除目录
os.rmdir(path)
12.2.6 遍历目录
os.walk(top,topdown,oneerro,followlinks)
12.3 高级文件操作
Python 内置的 os 模块除了可以对目录进行操作,还可以对文件进行一些高级操作,具体函数如下:
| 函数 | 说明 |
|---|---|
| access(path,accessmode) | 获取对文件是否有指定的访问权限 |
| chmod(path,mode) | 修改 path 指定文件的访问权限 |
| remove(path) | 删除 path 指定的文件路径 |
| rename(src,dst) | 将文件或目录 src 重命名为 dst |
| stat(path) | 返回 path 指定的文件信息 |
| startfile(path[,operation]) | 使用关联的应用程序打开 path 指定的文件 |
💬 评论
评论系统接入中...