1 变量
1.1 定义
变量:为快速定义目标,将数据在内存占据的存储空间分配的一个名称。
定义:变量名 = 数据值
作用:临时存储数据
message = "hello"
print(message)#输出:hello
message = "hello Python"
print(message)#输出:hello python
变量始终记录最新的值。
1.2 命名
-
变量名只能包含数字、字母、下划线,且不能以数字开头。
-
变量名不能包含空格,可以使用下划线来分割单词。
-
不能使用python关键字或函数名作为变量名。
查看python中的所有关键字:
import keyword print(keyword.kwlist)
-
建议使用驼峰命名法或下划线命名法:
大驼峰:VariableName(虽然不会导致错误,但尽量避免使用大写)
小驼峰:variableName
下划线:variable_name
1.3 id()
在Python中,id()
是一个内置函数,用于返回一个对象的唯一标识符,这个标识符通常是该对象在内存中的地址。这个函数在调试和了解对象的内存管理时非常有用。以下是id()
函数的一些关键特点和使用方法:
- 唯一性:在同一个Python解释器进程中,每个对象都有一个唯一的
id()
值。 - 稳定性:在对象的生命周期内,其
id()
值是恒定的,不会因为对象的内容改变而改变。 - 不可预测性:由于
id()
返回的是内存地址,因此它的具体值在不同的Python解释器运行实例或不同时间点上是不可预测的。 - 比较对象:
id()
函数常用于比较两个对象是否指向内存中的同一个位置。这与is
运算符的功能相似,但id()
提供了更底层的视角。 - 调试用途:在调试过程中,
id()
可以帮助开发者了解对象的创建和销毁情况,以及检测对象是否被重复使用。
以下是一个使用id()
函数的简单示例:
a = 10
b = a
c = 10print("id(a):", id(a)) # 输出a的内存地址
print("id(b):", id(b)) # 由于b是指向a的对象,所以它们的内存地址相同
print("id(c):", id(c)) # 由于a和c的值相同,所以会使用同一地址存储,内存地址相同# 使用is运算符比较对象身份
print("a is b:", a is b) # 应该返回True,因为a和b是同一个对象
print("a is c:", a is c) # 应该返回True,因为a和c的值相同,使用同一地址存储
2 输入与输出
2.1 输入与输出
a = input("这里是要显示到屏幕上的提示信息:")
print(a)
假设用户输入 Hello, World!
,程序的执行过程如下:
这里是要显示到屏幕上的提示信息:Hello, World!
Hello, World!
① input() 函数:
-
input("这里是要显示到屏幕上的提示信息:")
会在屏幕上显示提示信息 “这里是要显示到屏幕上的提示信息:”。 -
用户在看到提示后,可以在终端输入任意内容并按下回车键。
-
输入的内容会被作为字符串赋值给变量 a。
② print()函数:
print(a)
会将变量 a 中存储的内容输出到屏幕上。
2.2 格式化输出
①%操作符
- 这是一种较老的字符串格式化方法,灵感来源于C语言,已经逐渐被其他更先进的格式化方法取代。
- 例如:
print("姓名:%s,年龄:%d" % (name, age))
。 - %d:整数;%f:浮点数;%s:字符串
② str.format()方法
- 这个方法比
%
操作符提供了更多的灵活性。通过大括号{}
来设置占位符,并且可以通过索引或关键字来指定要插入的值。 - 例如:
print("姓名:{},年龄:{}".format(name, age))
。
③ F-string
- 自Python 3.6起,f-string成为了字符串格式化的一种非常高效和方便的方式。只需要在字符串前加上
f
或F
,并将变量放入大括号中即可。 - 例如:
print(f"姓名:{name},年龄:{age}")
。
3 数据类型
3.1 字符串
字符串就是一系列的字符。使用单引号或者双引号括起来。
'this is a string'
"this is a string"
在字符串中包含单引号或双引号:
"'this' is a string"
'"this" is a tring'
3.1.1 修改字符串的大小写
① 首字母大写:title()
str = "the case in strings"
print(str.title())#输出:The Case In Strings
② 全部大写:upper()
str = "the case in strings"
print(str.upper())#输出:THE CASE IN STRINGS
③ 全部小写:lower()
str = "The Case In Strings"
print(str.lower())#输出:the case in strings
3.1.3 添加空白
① 制表符 \t
str_list = ["hello","python"]
print("\t".join(str_list))
输出:hello python
② 换行符 \n
str_list = ["hello","python"]
print("\n".join(str_list))
输出:
hello
python
3.1.4 删除空白
① 删除字符串开头的空白:字符串.lstrip()
str = " python "
print(str.lstrip()) #输出:python
② 删除字符串结尾的空白:字符串.rstrip()
str = " python "
print(str.rstrip()) #输出: python
③ 删除字符串两边的空白:字符串.strip()
str = " python "
print(str.strip())#输出:python
print(str) #输出: python ,还是和输入时一样,两边还是包含空格,由此可见这种删除只是暂时的
这种删除只是暂时的,要永久删除,需要将删除后的结果存入变量:
str = " python "
str = str.strip()
print(str) #输出:python
3.2 数值类型
**① 布尔(bool)**:布尔类型用于表示逻辑值,只有两个取值:True和False。
② 整数(integer):用于表示所有的正整数、负整数和0。整数的进制表示方式包括十进制、二进制(0b或0B开头)、八进制(0o或0O开头)、十六进制(0x或0X开头)
③ 浮点数(float):用于表示带小数点的数字。浮点数也可以使用科学计数法表示,例如1.23e3
表示1.23×10^3。由于浮点数的存储方式,其运算可能会存在微小的误差。
④ 复数(complex):复数用于表示形如a + bj
的数,其中a
是实部,b
是虚部,j
是虚部单位。
3.2.1 使用str()避免类型错误
举个例子:
name = "小明"
age = 18
print(name + "今年" + age + "岁了")
执行程序将会发现引发了如下错误:
Traceback (most recent call last):File "F:\PythonWorkspath\hello.py", line 3, in <module>print(name + "今年" + age + "岁了")~~~~~~~~~~~~^~~~~
TypeError: can only concatenate str (not "int") to str
Python不知道age这个变量存储的是数值23,还是字符2和3,在字符串中使用正数时,需要使用str()
显示的指出,你希望将这个整数用作字符串:
name = "小明"
age = 18
print(name + "今年" + str(age) + "岁了") # 输出:小明今年18岁了
3.2.2 Python2 整数相除
在Python2中,整数相除的结果只会保留整数部分,小数部分会被自动删除。要避免这种情况,需要至少有一个操作数为浮点数。
a = 5 / 2
b = 5.0 / 2
c = 5 / 2.0
print(a) # 2
print(b) # 2.5
print(c) # 2.5
3.2.3 使用下划线_对数字分组
若数很大时,可使用下划线_对其分组,以便阅读。
注意:这种方法只有Python3.6及以上版本支持。
print(1_000_000_000_000_000) #输出:1000000000000000
3.2.4 同时为多个变量赋值
① 每个变量赋一个值
用逗号将变量名分开,变量的值也同样用逗号分开。变量和变量值的个数需相同。
举个例子:a,b,c = 1,2,3
等同于:
a = 1
b = 2
c = 3
② 一个变量赋多个值,使用*
*a,b,c = 1,2,3,4,5
print(a)#输出:[1,2,3]
print(b)#输出:4
print(c)#输出:5
③ 连续赋值:a = b = c = 10
3.2.5 常量
常量与变量类似,常量值在整个程序生命周期中始终保持不变。定义常量时,通常将常量名全部字母大写。
举个例子:CONSTANT = 1000
3.2.6 运算符
3.2.6.1 算术运算符
运算符 | 功能 | 示例 | 备注 |
---|---|---|---|
+ | 加法 | a + b | 除了算数运算,还可以拼接字符串 |
- | 减法 | a - b | |
* | 乘法 | a * b | |
/ | 除法 | a / b | |
% | 取模 | a % b | 返回余数 |
** | 幂 | a ** b | 返回a的b次方 |
// | 整除 | a // b | 返回商的整数部分(向下取整) |
Python还支持赋值运算符,如+=、*=等,它们可以简化赋值操作。例如,a += b等同于 a = a + b。
在Python中,算术运算符的优先级遵循以下规则:
- 幂运算:
**
,优先级最高,从右到左计算。 - 正负号:
+x
和-x
,用于一元加和减。 - 乘、除、取模和整除:
*
、/
、%
和//
,优先级次之,从左到右计算。 - 加法和减法:
+
和-
,优先级较低,同样从左到右计算。
3.2.6.2 逻辑运算符
Python中的逻辑运算符主要用于对布尔型变量进行运算,包括and
(逻辑与)、or
(逻辑或)和not
(逻辑非)。以下是这些运算符的具体用法和规则:
运算符 | 功能 | 示例 | 结果 |
---|---|---|---|
and | 逻辑与 | True and False | False |
or | 逻辑或 | True or False | True |
not | 逻辑非 | not True | False |
① 与(and)
- 当两个操作数都为
True
时,结果为True
。 - 如果任何一个操作数为
False
,结果为False
。 - 如果左边的表达式为
False
,则不会计算右边的表达式。
② 或(or)
- 当两个操作数中至少有一个为
True
时,结果为True
。 - 只有当两个操作数都为
False
时,结果为False
。 - 如果左边的表达式为
True
,则不会计算右边的表达式。
③非(not)
- 如果操作数为
True
,结果为False
。 - 如果操作数为
False
,结果为True
。
逻辑运算符的优先级为:()> not > and > or
3.2.6.3 比较运算符/关系运算符
运算符 | 名称 | 描述 | 示例 |
---|---|---|---|
== | 等于 | 如果两个操作数的值相等,则条件结果为True,否则为False | a == b |
!= | 不等于 | 如果两个操作数的值不相等,则条件结果为True,否则为False | a!= b |
> | 大于 | 如果左操作数的值大于右操作数的值,则条件结果为True,否则为False | a > b |
< | 小于 | 如果左操作数的值小于右操作数的值,则条件结果为True,否则为False | a < b |
>= | 大于等于 | 如果左操作数的值大于或等于右操作数的值,则条件结果为True,否则为False | a >= b |
<= | 小于等于 | 如果左操作数的值小于或等于右操作数的值,则条件结果为True,否则为False | a <= b |
is | 对象身份相等 | 如果两个变量引用同一个对象,则条件结果为True,否则为False | a is b |
is not | 对象身份不相等 | 如果两个变量引用不同的对象,则条件结果为True,否则为False | a is not b |
需要注意的是,is
和is not
运算符用于判断两个变量是否引用同一个对象,而==
运算符用于判断两个变量的值是否相等。
3.2.6.4 成员运算符
Python中的成员运算符主要用于判断一个元素是否存在于某个集合中。可以应用于多种数据类型,如字符串、列表、元组、集合和字典等。
① in
运算符
- 用于检查某个元素是否存在于给定集合中。
- 如果元素存在于集合中,则返回
True
;否则返回False
。 - 例如,
'a' in 'abc'
将返回True
,而'd' in 'abc'
将返回False
。
②not in
运算符
- 用于检查某个元素是否不存在于给定集合中。
- 如果元素不存在于集合中,则返回
True
;否则返回False
。 - 例如,
'a' not in 'abc'
将返回False
,而'd' not in 'abc'
将返回True
3.3 列表
适合⽤于存储在程序运⾏期间可能变化的数据集。
3.3.1 什么是列表
列表是一系列按特定顺序排列的元素组成。Python中用方括号([])来表示列表,并用逗号分割其中的元素。
list = ["one","two","three","four"]
print(list) #输出:['one', 'two', 'three', 'four']
3.3.2 访问列表元素
通过元素索引访问,需要注意的是:在Python中,列表中第一个元素的位置索引是0,第二个元素的位置是1。也可以通过索引-1访问最后一个元素,索引-2返回列表倒数第二个元素。
list = ["one","two","three","four"]
print(list[0]) # one
print(list[-1]) # four
print(list[1].title()) # Two
**注意:**如果列表中只包含4个元素,却访问第五个元素时,会导致索引错误:IndexError:list index out of range
如果列表为空,通过索引0或者-1访问列表元素时,也会导致索引错误。
3.3.3 修改列表元素
要修改列表元素,可通过元素索引定位要修改的元素,再指定该元素的新值。
list = ["one","two","three","four"]
list[0] = "1"
print(list) # 输出:['1', 'two', 'three', 'four']
3.3.4 在列表中添加元素
① 在列表末尾添加:append()
list = ["one","two","three","four"]
list.append("five")
print(list) # 输出:['one', 'two', 'three', 'four', 'five']
② 在指定位置插入元素:insert()
list = ["one","two","three","four"]
list.insert(0,"zero")
print(list) # 输出:['zero', 'one', 'two', 'three', 'four']
3.3.5 从列表中删除元素
① 删除指定位置的元素:del
list = ["one","two","three","four"]
del list[0]
print(list) #输出:['two', 'three', 'four']
使用del语句将元素从列表中删除后,就不能再访问被删除的元素了。
② 删除列表末尾的元素:pop()
方法pop()可删除列表末尾的元素,并可以使用变量接收被删除的元素,以便后续继续使用。
list = ["one","two","three","four"]
del_element = list.pop()
print(list) #输出:["one","two","three"]
print(del_element)#输出:four
③ 删除指定位置的元素:pop()
方法pop()还可以删除指定位置的元素,只需要在括号中加入位置索引。
list = ["one","two","three","four"]
del_element = list.pop(1)
print(list) #输出:['one', 'three', 'four']
print(del_element) #输出:two
④ 根据值删除元素:remove()
我们不知道元素的位置,只知道待删除的元素值是什么的时候,可以使用此方法。
list = ["one","two","three","four"]
list.remove("two")
print(list) #输出:['one', 'three', 'four']
温馨提示:如果待删除的值在列表中出现多次,remove()方法只会删除列表中第一个指定的值。
⑤ 删除列表中的所有元素,清空列表:clear()
如果我们想删除列表中的所有元素,得到一个空列表,可以使用clear()方法。
arrs = [1,2,3,4,5]
arrs.clear()
print(arrs) #输出:[]
3.3.6 列表排序
① 对列表进行永久性排序:sort()
使用sort()方法会永久性改变列表的排列顺序,之后无法再恢复。
list = ['a','d','e','c','b']
list.sort()
print(list) #输出:['a', 'b', 'c', 'd', 'e']
还可以给sort()方法传递参数reverse = True,进行降序排列。
list = ['a','d','e','c','b']
list.sort(reverse = True)
print(list) #输出:['e', 'd', 'c', 'b', 'a']
② 对列表进行临时排序:sorted()
sorted()函数可以让列表元素按特定的顺序显示,但是不改变列表元素原来的排序。
list = ['4','6','8','1','7']
print(sorted(list)) #输出:['1', '4', '6', '7', '8']
print(list) #输出:['4', '6', '8', '1', '7']
也可以给sorted()函数传递参数reverse = True,让列表元素进行降序排列。
list = ['4','6','8','1','7']
print(sorted(list,reverse = True)) # 输出:['8', '7', '6', '4', '1']
print(list) #输出:['4', '6', '8', '1', '7']
③ 列表反转:reverse()
该方法会永久性的改变列表的排序,但可以再次调用reverse()方法,使列表元素变回原来的排序。
list = ['4','6','8','1','7']
list.reverse()
print(list) #输出:['7', '1', '8', '6', '4']
list.reverse()
print(list) #输出:'4','6','8','1','7'
3.3.7 获取列表长度
使用函数len()获取列表长度。
list = ['4','6','8','1','7']
print(len(list)) #输出:5
3.3.8 遍历列表
可以使用for循环来遍历列表:for 变量名 in 列表:
areas = ['beijin','xiyatu','aomen']
for area in areas:print(area)
执行程序,输出如下:
beijin
xiyatu
aomen
对于列表中的每个元素,在程序执行过程中,Python都会重复的将其取出存储在area中,然后再将其打印出来,直至列表中没有其他的值了。
3.3.9 使用range()函数创建数值列表
range()
函数生成一段左闭右开的整数范围。语法:range(start,end,step)
,start表示起始值,默认为0;end表示结束值,但不包括end;step为步长,默认为1。
for num in range(-2,6,2):print(num)
执行程序,程序从-2开始,依次加2,直至超过结束值6,输出:
-2
0
2
4
可以使用list()函数直接将range()的结果转换为一个列表,range()作为list()的参数。
print(list(range(-2,6,2))) #输出:[-2, 0, 2, 4]
3.3.10 统计数值列表
最大值:max()
最小值:min()
求和:sum()
nums = list(range(-2,6,2))
print(nums) #[-2, 0, 2, 4]
print(max(nums)) #最大值:4
print(min(nums))#最小值:-2
print(sum(nums))#合计:4
3.3.11 列表解析(列表推导式)
我们先来使用之前的方法来创建一个数字列表,列表包含1-3的平方。
nums = []
for i in range(1,4):nums.append(i ** 2)print(nums) #执行程序,输出:[1,4,9]
接下来我们使用列表解析,创建一个相同的数字列表,包含1-3的平方。
nums = [i ** 2 for i in range(1,4)]
print(nums) #执行程序,输出:[1,4,9]
列表解析将for循环和添加新元素的代码合并到一行。for循环(for i in range(1,4))将每次循环的值供给表达式(i ** 2)
3.3.12 列表切片
切片,即处理列表中的部分元素。创建切片,需指定要使用的第一个元素和最后一个元素的索引,类似range()函数。语法:列表名[start:end:step]
,start表示起始值,默认为0;end表示结束值,但不包括end;step为步长,告诉Python每隔几个元素提取一个。字符串也可以切片。
nums = ['5','4','6','8','2','11','13']
print(nums[1:6:2])#输出:['4', '8', '11']
print(nums[:6])#输出:['5', '4', '6', '8', '2', '11']
print(nums[1:])#输出:['4', '6', '8', '2', '11', '13']
print(nums[::2])#输出:['5', '6', '2', '13']
print(nums[-1:-4:-2])#输出:['13', '2']
3.3.13 复制列表
可以使用列表切片复制列表。
# coding: gbk
tabulation = [1,2,3,4]
tabulation_cp = tabulation[:]
print(tabulation_cp) #输出:[1,2,3,4]
tabulation_cp.append(5)
print(tabulation_cp) #输出:[1,2,3,4,5]
print(tabulation)#输出:[1,2,3,4]
我们现在来试一试不适用切片,直接赋值:
tabulation = [1,2,3,4]
tabulation_cp = tabulation
print(tabulation_cp) #输出:[1,2,3,4]
tabulation_cp.append(5)
print(tabulation_cp) #输出:[1,2,3,4,5]
print(tabulation)#输出:[1,2,3,4,5]
使用切片,tabulation_cp = tabulation[:]
相当于把tabulation的副本赋给tabulation_cp;而tabulation_cp = tabulation
实际上是将tabulation_cp关联到tabulation,这两个变量实际是指向的同一个列表。
3.3.14 合并列表
可以使用extend()
将两个列表合并成一个列表。
lst1 = [1,2,3]
lst2 = [4,5,6]
lst1.extend(lst2)#直接修改lst1,如果使用变量接收lst1.extend(lst2),会返回None
print(lst1)#输出:[1, 2, 3, 4, 5, 6]
3.4 元祖
3.4.1 什么是元祖
元祖相当于不可变的列表。如果需要创建一系列不可改变的元素,可以使用元祖。定义:元祖名 = (元素1,元素2...元素3)
,严格来说,元祖是由逗号标识的,如果我们要定义只包含一个元素的元祖,必须在这个元素后面加上括号:元祖名 = (元素,)
(定义只包含一个元素的元祖是没有意义的,但是自动生成的元祖可能只包含一个元素。)
3.4.2 访问元祖元素
可以通过元素索引访问元祖中的元素,与访问列表元素方法相同。
tuple1 = (5,6,7)
print(tuple1[0]) #输出:5
3.4.3 不能修改元祖元素
我们来尝试修改元祖中的元素:
tuple1 = (5,6,7)
tuple1[0] = 10
执行程序,Python会返回错误信息:
Traceback (most recent call last):File "F:\PythonWorkspath\list_sty.py", line 2, in <module>tuple1[0] = 10TypeError: 'tuple' object does not support item assignment
3.4.4 修改元祖变量
虽然不能修改元祖变量,但是可以给元祖变量赋值。
# coding: gbktuple1 = (5,6,7)
print(f"为元祖变量赋值前的元祖:{tuple1}")tuple1 = (1,2,3)
print(f"为元祖变量赋值后的元祖:{tuple1}")
执行程序,输出:
为元祖变量赋值前的元祖:(5, 6, 7)
为元祖变量赋值后的元祖:(1, 2, 3)
3.4.5 遍历元祖
同列表,使用for循环遍历列表:
tuple1 = (5,6,7)
for i in tuple1:print(i)
执行程序,输出:
3
6
7
3.5 字典
3.5.1 什么是字典
在 Python 中,字典是⼀系列键值对。每个键都与⼀个值关联,可以使⽤键来访问与之关联的值。与键相关联的值可以是数字、字符串、列表或是字典。字典⽤放在花括号({})中的⼀系列键值对表⽰,键和值之间⽤冒号分隔,⽽键值对之间⽤逗号分隔。
定义:字典名 = {键1:值1,键2:值2...键n:值n}
# 可以使用多行来定义字典。
# 可以在最后一个键值对后面加上逗号(,),方便以后添加键值对。
scores = {'语文':80,'数学':95,'英语':88,'化学':99,
}
3.5.2 查询字典中的值
可以直接使用字典名[键名]
来查询对应的值:
# coding: utf-8
stu_info = {'name':'张三','age':18,'hobby':'打球','tel':'13333333333'}
print(stu_info['tel'])#输出:13333333333
查询时,如果指定的键不存在,Python会报错:
# coding: utf-8
stu_info = {'name':'张三','age':18,'hobby':'打球','tel':'13333333333'}
print(stu_info['email'])
执行程序,输出:
Traceback (most recent call last):File "F:\PythonWorkspath\hello.py", line 3, in <module>print(stu_info['email'])~~~~~~~~^^^^^^^^^
KeyError: 'email'
为避免这样的错误,可以使用get()方法,该方法有两个参数,第一个参数用于指定键,第二个用于指定键不存在时返回的值,默认为None。
# coding: utf-8stu_info = {'name':'张三','age':18,'hobby':'打球','tel':'13333333333'}
print(stu_info.get('email','没有邮箱信息'))#输出:没有邮箱信息
print(stu_info.get('email'))#输出:None
3.5.3 创建字典
可以使用花括号定义一个空字典,然后再添加各个键值对。
# coding: utf-8stu_info = {}
stu_info['name'] = 'zhangsan'
stu_info['age'] = 18
print(stu_info) #输出:{'name': 'zhangsan', 'age': 18}
使用update()方法,可以将一个字典中的元素添加到另一个字典中,如果两个字典中的键重复,这个字典中的值将会被更新。
dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
dict2 = {'key3': 'value4', 'key4': 'value4'}
dict1.update(dict2)#将dict2的元素添加到dict1中,dict1和dict2中都存在键key3,使用update()后,dict1中key3的值被更新了
print(dict1) #输出:{'key1': 'value1', 'key2': 'value2', 'key3': 'value4', 'key4': 'value4'}
3.5.4 删除
① 使用pop()方法
dict.pop(key,'键不存在时返回的值')
根据指定的键删除字典中的元素,并返回该键对应的值。如果键不存在,可以提供一个默认值避免异常。
my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
print(my_dict.pop('key2',"不存在时返回的值")) # 删除键为'key2'的元素,并返回'value2'
print(my_dict) # 输出:{'key1': 'value1', 'key3': 'value3'}
② 使用del语句
del语句可以用来删除字典中指定键的元素。如果键不存在,将引发KeyError异常。
my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
del my_dict['key2'] # 删除键为'key2'的元素
print(my_dict) # 输出:{'key1': 'value1', 'key3': 'value3'}
③ 使用popitem()方法
该方法用于删除并返回字典中的最后一个键值对。如果字典为空,将引发KeyError异常。
my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
my_dict.popitem() # 删除并返回最后一个键值对
print(my_dict) # 输出:取决于字典中的顺序
④ 使用clear()方法
该方法用于清空整个字典。
my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
my_dict.clear() # 清空字典
print(my_dict) # 输出:{}
⑤使用推导式
my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
new_dict = {key: value for key, value in my_dict.items() if key!= 'key2'}
print(new_dict) # 输出:{'key1': 'value1', 'key3': 'value3'}
3.5.5 修改
① 直接赋值
如果知道键的名称,可以直接通过赋值操作来修改该键对应的值。如果键不存在,则会添加一个新的键值对。
dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
dict1["key4"] = "value4"
print(dict1)
② 使用update()方法
这个方法可以用来更新一个或多个键的值。如果提供的键在原字典中不存在,则会添加新的键值对。
dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
dict2 = {'key3': 'value4', 'key4': 'value4'}
dict1.update(dict2)#将dict2的元素添加到dict1中,dict1和dict2中都存在键key3,使用update()后,dict1中key3的值被更新了
print(dict1) #输出:{'key1': 'value1', 'key2': 'value2', 'key3': 'value4', 'key4': 'value4'}
③ 使用setdefault()方法
这个方法可以用来设置默认值。如果键存在,则返回该键对应的值;如果键不存在,则插入键并设置默认值。
dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
dict1.setdefault("key4","value4")
print(dict1)
3.5.6 遍历字典
可以使用字典名.keys()
获取字段中的键.
使用字典名.values()
获取字段中的值.
使用字典名.items()
获取字典中的键值对.
使用sorted()
进行排序.
scores = {'语文':80,'数学':95,'英语':88,'化学':99,
}for subject in scores.keys():print(subject)for score in sorted(scores.values()):print(score)for subject,score in scores.items():print(subject+":"+str(score))
执行程序,输出:
语文
数学
英语
化学
80
88
95
99
语文:80
数学:95
英语:88
化学:99
可以使用set()函数剔除重复项.
# coding: gbk
scores = {'语文':80,'数学':95,'英语':88,'化学':99,"体育":99,
}for score in set(scores.values()):print(score)
执行程序,输出:
80
99
88
95
3.5.7 复制字典
可以使用copy()
复制字典的所有值。
dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
dict1_cp = dict1.copy() #复制字典
print(dict1_cp)#输出:{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
3.6 集合
Python集合(set)是一个无序的不重复元素序列,集合在很多场景中有用,比如去除重复的数据,快速判断元素是否存在等。可以使用大括号{}或set()函数创建集合。
注意:创建空集合必须使用set(),因为{}用于创建空字典。
3.6.1 创建集合
# 创建一个空集合
s = set()# 创建一个有内容的集合
s1 = {'a', 'b', 'c'}
print(s1) # 输出:{'a', 'c', 'b'}# 使用set函数创建集合
s2 = set(['a', 'b', 'c'])
print(s2) # 输出:{'a', 'c', 'b'}
3.6.2 集合的基本操作
# 集合添加元素
s1 = {'a', 'b', 'c'}
s1.add('d')
print(s1) # 输出:{'d', 'a', 'c', 'b'}# 集合删除元素
s1.remove('b')#删除指定的元素,如果元素不存在,会抛出错误KeyError
print(s1) # 输出:{'a', 'c', 'b'}
s1.discard('a')#删除指定元素,元素不存在也不会报错
print(s1) #输出:{'c', 'd'}
s1.pop()#随机删除元素
print(s1)# 返回其元素个数
print(len(s1)) # 输出:1# 判断元素是否在集合中
print('a' in s1) # 输出:False# 遍历集合元素
for item in s1:print(item)# 集合清空
s1.clear()
print(s1) # 输出:set()
3.6.3 集合运算
s1 = {'a', 'b', 'c'}
s2 = {'b', 'c', 'd'}# 交集
print(s1 & s2) # 输出:{'b', 'c'}# 并集
print(s1 | s2) # 输出:{'a', 'c', 'b', 'd'}# 差集
print(s1 - s2) # 输出:{'a'}# 对称差集
print(s1 ^ s2) # 输出:{'a', 'd'}# 判断集合是否包含另一个集合
print(s1 > s2) # 输出:False
print(s1 < s2) # 输出:False
3.7 类型转换
Python是一种动态类型语言,变量在声明时不需要指定其数据类型。然而,在某些情况下,可能需要将一个数据类型转换为另一个数据类型。Python提供了以下几种方法来进行类型转换:
① 隐式类型转换:Python在执行某些操作时会自动进行类型转换。例如,当您将一个整数与一个浮点数相加时,结果会自动转换为浮点数。
num_int = 1
num_float = 1.5
result = num_int + num_float # 结果为2.5,自动转换为浮点数
② 显式类型转换:如果您需要明确地将一个变量从一种数据类型转换为另一种数据类型,可以使用内置的类型转换函数。以下是一些常用的类型转换函数:
int()
: 将一个数值或字符串转换为整数。
# 将浮点数转换为整数(小数部分会被截断)
num_float = 20.7
num_int = int(num_float)
print(num_int) # 输出: 20# 将字符串转换为整数
num_str = "42"
num_int = int(num_str)
print(num_int) # 输出: 42
float()
: 将一个数值或字符串转换为浮点数。str()
: 将一个对象转换为字符串。list()
: 将一个可迭代对象(如元组、字符串等)转换为列表。tuple()
: 将一个可迭代对象转换为元组。set()
: 将一个可迭代对象转换为集合。dict()
: 将一个包含键值对的序列转换为字典。
以下是一些使用显式类型转换的示例:
# 将浮点数转换为整数
num_float = 20.5
num_int = int(num_float) # 结果为20,小数部分被截断# 将字符串转换为整数
num_str = "42"
num_int = int(num_str) # 结果为42# 将字符串转换为浮点数
num_str = "3.14"
num_float = float(num_str) # 结果为3.14# 将列表转换为元组
my_list = [1, 2, 3]
my_tuple = tuple(my_list) # 结果为(1, 2, 3)
请注意,当使用int()
或float()
函数将字符串转换为数值时,如果字符串不能直接转换(例如,它包含非数字字符),则会引发ValueError
异常。
4 条件分支结构
Python中主要有三种条件分支结构:单分支结构、二分支结构和多分支结构。
① 单分支结构
- 单分支结构是最简单的条件判断形式。它只包含一个
if
语句,当条件满足时执行相应的代码块。如果条件不满足,则跳过代码块,继续执行后续代码。语法如下:
if <条件>:<语句块>
② 二分支结构
- 二分支结构在条件满足和不满足时分别执行不同的代码块。它由
if
和else
组成。语法如下:
if <条件>:<语句块1>
else:<语句块2>
③ 多分支结构
- 多分支结构可以处理多个条件的情况。它通过
if
、elif
(可选多个)和else
(可选)组成。语法如下:
pythonif <条件1>:<语句块1>
elif <条件2>:<语句块2>
...
else:<语句块N>
在编写条件分支结构时,需要注意以下几点:
- 缩进:Python使用缩进来表示代码块,错误的缩进会导致语法错误。
- 条件表达:条件表达式应该返回一个布尔值(True或False)。
- 逻辑运算符:可以使用
and
、or
和not
来组合多个条件。 - 优先级:注意操作符的优先级,必要时使用括号来明确运算顺序。
5 while 循环
Python中的while
循环是一种控制流程结构,用于重复执行一段代码块,直到指定的条件不再满足。while
循环的基本语法结构如下:
while <条件>:<代码块> # 当条件为真时执行的代码
在每次迭代开始之前,Python会评估条件表达式的值。如果条件为真(True
),则执行循环体内的代码块。如果条件为假(False
),则跳出循环,继续执行循环之后的代码。
循环控制
- break:立即终止循环,执行循环之后的代码。
- continue:跳过当前迭代中剩余的代码,直接开始下一次迭代。
- else:在循环正常结束时(未通过
break
跳出)执行。
示例
① 计数循环
lst=[4,7,8,2,99,10,22,33,64,23,12,45,111,23] #定义一个纯整数的列表
index=0 # 定义初始化索引值
max_value =lst[0] #初始化最大值为列表的第一个元素while index<len(lst): # 只要索引小于列表的长度,证明我们没有比较完所有的元素,还要继续循环执行if lst[index]>max_value:# 如果当前元素大于当前最大值max_value=lst[index] # 更新最大值index +=1
print("列表中的最大值是:",max_value) # 打印出找出到最大值
②无限循环
while True:user_input = input("请输入命令:")if user_input == "quit":break # 通过用户输入终止循环
③ 使用else
i = 2
while i > 0:print("ok")i -= 1
else:print("no") # 当循环正常结束时执行
注意事项
- 确保循环中有改变条件表达式的代码,以避免无限循环。
- 合理使用
break
和continue
来控制循环流程。
6 for循环
for
循环用于遍历序列(如列表、元组、字符串)或其他可迭代对象中的元素。
for variable in iterable:
# 执行的代码块
iterable
是一个可迭代对象,variable
是在每次迭代中接收iterable
中下一个值的变量。
① 遍历不同类型的对象
- 列表:
for item in my_list: print(item)
。 - 字符串:
for char in my_string: print(char)
。 - 范围:
for i in range(5): print(i)
,range(5)
生成从0到4的整数序列。 - 字典:
for key in my_dict.keys(): print(key)
或for key, value in my_dict.items(): print(key, value)
。
② 列表推导
列表推导是一种简洁的方式,通过for
循环生成新的列表。例如,squares = [x**2 for x in range(10)]
将生成一个包含0到9的平方值的列表。
③ 嵌套循环
在一个for
循环内部可以嵌套另一个for
循环,用于处理二维数据或其他需要多层迭代的情况。
-
打印9*9乘法表:
for i in range(1,10):for j in range(1,i+1):print(f"{j}*{i}={i*j}",end=" ")print()
-
冒泡排序
lst = [1,6,8,9,3,4,5,] # 第一层循环,控制比较的轮次 for i in range(len(lst)-1):# 第二层循环,控制每轮比较的次数for j in range(len(lst) - i - 1):if lst[j] > lst[j+1]:lst[j],lst[j+1] = lst[j+1],lst[j] print(lst)
④ 循环控制语句
break
:立即退出循环。continue
:跳过当前迭代,继续下一次迭代。else
:如果循环正常结束(没有遇到break
),则执行else
从句中的代码。
⑤使用enumerate
- 如果需要在循环中同时获取元素的索引和值,可以使用
enumerate
函数。例如,for i, item in enumerate(my_list): print(i, item)
。
7 函数
7.1 函数定义
def function_name(parameters):# 函数体return result
7.2 函数调用
调用函数时,可以按照参数类型传递实际参数。调用函数时,Python解释器会将实际参数与形式参数匹配,并执行函数体中的代码。
result = function_name(arguments)
7.3 参数
7.3.1 形参
形参:在函数定义中声明的变量,它们在函数被调用之前没有具体的值,当函数被调用时,这些形参将被赋予实际的值(实参)。
① 缺省参数:为函数参数提供默认值,如果调用时未传递该参数,将使用默认值。
def person(name,age,sex = '女'):print("姓名:{},年龄:{},性别:{}".format(name,age,sex))
person('angel',18)#输出:姓名:angel,年龄:18,性别:女
person('bob',18,sex='男')#输出:姓名:bob,年龄:18,性别:男
② 不定长参数:使用 *args
和 **kwargs
接收任意数量的位置参数和关键字参数。
-
不定长位置参数(
*args
):*args
会将传入的多个位置参数收集到一个元组中。def sum(*args):result = 0for i in args:result += ireturn result print(sum(1,2,3))
-
不定长关键字参数(
**kwargs
):**kwargs
会将传入的多个关键字参数收集到一个字典中。def person(**kwargs):for key,value in kwargs.items():print("{}:{}".format(key,value)) person(name="bob",age=18,sex="man")
执行程序,输出:
name:bob age:18 sex:man
7.3.2 实参
实参:调用函数时传递给函数的具体值。
① 位置参数:在调用函数时,按照参数的顺序依次传递给函数的参数。这些参数的值必须严格按照函数定义中的顺序传递,位置参数的数量与函数定义时的参数数量需要一致。
def sum(a,b):#函数sum(a,b)定义了两个位置参数a和breturn a + b
result = sum(2,3)#调用sum(2,3)时,Python会将2的值赋给a,3的值赋给b
print(result)
② 关键字参数:在调用函数时,通过指定参数名为参数赋值。在调用函数时,可以同时使用位置参数和关键字参数。但位置参数必须在关键字参数之前,否则会引发语法错误。
def area(long,wide):return long * wide
result = area(wide = 5,long = 3)#使用了关键字参数,调用时参数的顺序可以不同于函数定义中的顺序
print(result)
def area(long,wide):return long * wide
result = area(5,wide = 3)#同时使用位置参数和关键字参数,位置参数必须在前,如果调用area(long = 5,3)会引发语法错误SyntaxError
print(result)
7.4 返回值
使用 return
将函数的结果返回给调用者。return
之后的代码不会被执行。若一个函数没有return
,就会返回None
,如果return
后面没有具体的返回值,也会返回None
。
7.5 变量作用域
Python中的变量作用域分为全局变量和局部变量。
全局变量:在整个程序范围内都可访问的变量,通常在函数外部定义。
局部变量:只在其被定义的特定区域(如函数内)内可访问,在函数内部定义。如果要在函数内部修改全局变量的值,需要使用global
关键字进行声明。
x = 100 #定义一个全局变量X
def mofidy_num():x = 99 #这里相当于创建了一个局部变量x,而并非修改全局变量x
mofidy_num()
print(x) #输出:100
x = 100 #定义一个全局变量X
def mofidy_num():global x # 使用global关键字声明要修改的变量是全局变量x = 99
mofidy_num()
print(x) #输出:99
def mofidy_num():global x #在函数内将变量x声明成全局变量x = 99
mofidy_num()
print(x) #输出:99
7.6 递归函数
递归:函数直接或间接调用自身的过程。
def f(n):if n == 1 or n == 0:return 1else:return n * f(n-1)
print(f(4))
7.7 函数的注释
① 单行注释:使用三个单引号或双引号包裹起来,并且紧跟在函数定义的下一行。
def sum(a,b):"""返回两个数的和"""return a + b
② 多行注释:同样是用三个单引号或双引号,在函数内部可以有多行内容。
def sum(a,b):"""这个函数用来求两个数的和:param a: 第一个加数:param b: 第二个加数:return: 返回两个数的求和结果"""return a + b
③ 从注释中获取信息:
-
使用
__doc__
print(sum.__doc__)#输出:以上程序三个双引号之间的内容
-
使用
help()
help(sum)#输出:以上程序三个双引号之间的内容
7.8 函数嵌套
函数嵌套是指在一个函数内部定义另一个函数。
7.8.1 定义
def outer():print("这是外部函数")def inner():print("这是内部函数")inner()
outer()#当调用outer时,它会先打印出"这是外部函数",然后调用内部的inner打印出"这是内部函数"。
7.8.2 嵌套函数的返回值
① 返回内部函数
def outer():def inner():return 5return innerfunc = outer()#outer函数返回inner函数,然后将返回的函数赋值给func变量
print(func())#调用func得到内部函数的返回值5
② 闭包:闭包通常由一个外部函数和一个内部函数组成,内部函数可以访问外部函数的局部变量,即使外部函数已经执行完毕,这些变量仍然会被保留在内存中。闭包在Python中有多种用途:
- 装饰器:闭包是实现装饰器的基础,装饰器可以用来增强函数的功能,而无需修改原函数的代码。
- 函数工厂:闭包可以用来创建一系列相似的函数,每个函数有不同的初始状态。
- 回调函数:将函数作为参数传递,使得函数能够在未来的某个时刻被调用。
需要注意的是,由于闭包保留了外部函数的变量,这些变量会一直存在于内存中,直到闭包函数不再被引用。这可能会影响内存管理。
闭包的特点:
- 函数嵌套:闭包存在于函数嵌套的情况下,即一个函数内部定义了另一个函数。
- 变量访问:内部函数可以访问外部函数的变量。
- 返回函数:外部函数返回内部函数,这样内部函数可以在外部函数执行完毕后仍然被调用。
- 变量持久性:闭包使得外部函数的变量在外部函数执行完毕后仍然保持其值,不会被垃圾回收机制回收。
def outer(y):def inner(x):return x + yreturn inneradd = outer(5)#当outer被调用时,它返回一个闭包,这个闭包包含inner和y的值5,将这个闭包复制给add
print(add(3)) #调用add(3),传入x=3,返回3+5的值5
7.8.3 嵌套函数的参数传递
如果参数是可变对象,内部函数可以修改外部函数的参数。
def outer(lst):def inner():lst.append(4)inner()return lstmy_list = [1, 2, 3]
new_list = outer(my_list)
print(new_list)#输出:[1, 2, 3, 4]
7.9 数学相关的内置函数
① abs(x) : 返回x绝对值
print(abs(-99)) #输出99
② divmod(x,y) : 返回x/y的商和余数
x,y = divmod(8,3)
print(f"商:{x}")#输出:商:2
print(f"余数:{y}")#输出:余数:2
③ round(x,y):x为需要四舍五入的浮点数;y(可选)指定小数点后保留的位数。如果不提供,默认为0,即保留整数。
特殊规则:
-
银行家舍入法:当数字处于两个整数的中间时,
round()
函数会遵循“银行家舍入法”(例如,2.5四舍五入为2,3.5四舍五入为4。 -
负数的处理:对于负数,
round()
函数采用“远离零的方向舍入”的方式。例如,-2.5四舍五入为-3,-3.5四舍五入为-4。print(round(3.5))#输出:4 print(round(4.5))#输出:4 print(round(-3.5))#输出:-4 print(round(-4.5))#输出:-4 print(round(2.465,2))#输出:2.46 print(round(2.455,2))#输出:2.46
④ pow(x,y) : x的y次方
print(pow(2,3))#输出:8
⑤ sum(s): 返回序列s的和
⑥ min(s): 返回序列s的最小值
⑦ max(s) : 返回序列s的最大值
lst = [1,2,3,4]
print(sum(lst)) #输出:10
print(min(lst)) #输出:1
print(max(lst)) #输出:4
7.10 匿名函数
add = lambda x, y: x + y
result = add(3, 5)
print(result)
这里lambda x, y: x + y
就是一个匿名函数,它接受两个参数x
和y
,并返回它们的和。匿名函数只能有一个表达式,不能包含多条语句或者复杂的逻辑结构
7.11 装饰器
Python装饰器是一种特殊的函数,用于修改或增强其他函数的功能,而无需修改原函数的代码。装饰器的本质是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数作为结果。装饰器一般用于:
- 日志记录:在函数执行时自动记录日志,方便调试和监控。
- 性能测量:测量函数的执行时间,帮助优化性能。
- 访问控制:限制对某些函数的访问,例如基于用户权限。
- 缓存:存储函数的计算结果,以提高效率。
- 输入验证:在函数执行前验证输入参数的有效性。
7.11.1 一个基本的装饰器
import time# 定义一个装饰器函数,它接收一个函数作为参数
def my_decorator(func):# 定义一个包装器函数,它将包含额外的功能(在这里是测量时间)def wrapper():# 记录函数开始执行前的时间t1 = time.time()# 执行被装饰的函数func()# 记录函数执行后的时间t2 = time.time()# 打印函数执行所需的总时间print(f"total time: {t2 - t1}")# 返回包装器函数,以便它可以替换被装饰的函数return wrapper# 使用装饰器装饰multiplication_table函数
@my_decorator
def multiplication_table():# 打印乘法表for i in range(1, 10):for j in range(1, i + 1):print(f"{j} * {i} = {i * j}", end=' ')print()# 调用被装饰的函数,它将打印乘法表并显示执行时间
multiplication_table()
7.11.2 带参数的装饰器
import time# 定义一个装饰器函数,它接收一个函数作为参数
def my_decorator(func):# 定义一个包装器函数,它将包含额外的功能(在这里是测量时间)def wrapper(*args, **kwargs):# 记录函数开始执行前的时间t1 = time.time()# 执行被装饰的函数,并保存其返回值r = func(*args, **kwargs)# 记录函数执行后的时间t2 = time.time()# 打印函数执行所需的总时间print(f"total time: {t2 - t1:.6f} seconds")# 返回被装饰函数的返回值,被装饰的函数没有返回值,不返回这个值程序也可以正常运行,但是最好总是返回被装饰函数的返回值(如果有的话)return r# 返回包装器函数,以便它可以替换被装饰的函数return wrapper# 使用装饰器装饰multiplication_table函数
@my_decorator
def multiplication_table(min_num, max_num):# 打印乘法表for i in range(min_num, max_num):for j in range(min_num, i + 1):print(f"{j} * {i} = {i * j}", end=' ')print()# 调用被装饰的函数,它将打印乘法表并显示执行时间
multiplication_table(1, 10)
7.11.3 装饰器工厂
装饰器工厂是一个返回装饰器的函数,可以在创建装饰器时传递参数。工厂函数返回一个实际的装饰器,这个装饰器接受一个函数作为参数,装饰器返回一个新的函数(通常会包含原函数的调用和一些额外的逻辑)。
import timedef decorator_factory(do_something):def my_decorator(func):def wrapper(*args, **kwargs):# 打印传入的字符串参数print(do_something)# 记录函数执行前的时间t1 = time.time()# 调用原始函数并获取结果r = func(*args, **kwargs)# 记录函数执行后的时间t2 = time.time()# 打印函数执行时间print("total time: {:.6f}".format(t2 - t1))# 返回原始函数的结果return rreturn wrapperreturn my_decorator# 使用装饰器工厂装饰函数,并传入字符串参数
@decorator_factory(do_something="hello")
def show_time(t):time.sleep(t)# 调用被装饰的函数
show_time(5)
7.11.4 链式装饰器
多个装饰器作用于同一个函数。
import timedef timing_decorator(func):def wrapper(*args, **kwargs):t1 = time.time()result = func(*args, **kwargs)t2 = time.time()print(f"total time:{t2 - t1 }s")return resultreturn wrapperdef logging_decorator(func):def wrapper(*args, **kwargs):print(f"调用函数{func.__name__},参数args:{args},kwargs:{kwargs}")result = func(*args, **kwargs)print(f"{func.__name__} 返回的结果是: {result}")return resultreturn wrapper@timing_decorator
@logging_decorator #由于装饰器是从上到下应用的,所以实际上是 logging_decorator 先执行,然后是 timing_decorator
def my_function(x, y):time.sleep(3) # 模拟耗时操作return x + y# 调用函数
print(my_function(2, 3))
应用场景:
-
日志记录:可以使用多个装饰器分别记录函数调用的不同方面,如调用时间、参数信息、返回值等。
-
权限验证与性能监控:一个装饰器用于验证用户是否有调用函数的权限,另一个装饰器用于计算函数的执行时间以进行性能监控。
8 模块
Python 模块是包含 Python 代码的文件,其文件名是模块名加后缀名.py
。模块可以包含函数、变量和类,并且可以在其他 Python 程序中导入和使用。
8.1 导入模块
① 导入整个模块:import 模块名
import module_name# 使用模块中的函数或变量
module_name.my_function()
print(module_name.my_variable)
② 导入模块中的一部分: from 模块名 import 函数名
from module_name import my_function# 直接使用导入的函数
my_function()
③ 导入包中的模块:from 包名 import 模块名
from package_name import module_name# 使用模块中的函数或变量
module_name.my_function()
print(module_name.my_variable)
④ 导入模块中的所有成员(不推荐,可能会导致命名冲突):from 模块名 import *
from module_name import *# 直接使用模块中的任何函数、类或变量
my_function()
print(my_variable)
⑤ import 模块名 as 别名
:如果模块名很长或者你想要给模块一个更具描述性的名字,你可以使用 as
关键字来为模块指定一个别名。
import module_name as name# 使用别名来访问模块的内容
name.my_function()
8.2 标准库模块
https://docs.python.org/zh-cn/3.11/library/index.html
8.3 自定义模块
要创建自定义模块,只需将Python代码保存到一个以.py
结尾的文件中。例如,创建一个名为mymodule.py
的文件,并在其中定义函数、类和变量。然后,在其他Python文件中通过import mymodule
来导入该模块。
8.4 第三方模块
通常由Python社区或第三方开发者创建和维护,用于扩展Python的功能。与Python的标准库(Standard Library)不同,标准库是随Python解释器一同安装的,无需额外安装即可使用。而第三方模块则需要通过包管理工具(如pip)进行安装。
Selenium:用于Web应用程序的自动化测试,可以模拟用户在浏览器中的操作。
Appium:用于移动应用程序的自动化测试,支持Android和iOS平台。
TestNG:一个测试框架,提供了更丰富的测试功能和报告。
JUnit:Java语言的单元测试框架,用于编写和运行单元测试。
PyTest:Python语言的测试框架,提供了简单而强大的测试功能。
Cucumber:行为驱动开发(BDD)框架,用于编写可读性强的测试用例。
TestComplete:一个功能强大的自动化测试工具,支持多种应用程序和平台。
RobotFramework:一个通用的自动化测试框架,支持关键字驱动和数据驱动的测试。
Mockito:Java语言的模拟框架,用于创建和管理测试中的模拟对象。
Jasmine:JavaScript语言的行为驱动开发(BDD)框架,用于编写和运行前端测试。
8.5 包
包是包含多个模块的目录(文件夹),它通常还包含一个特殊的文件__init__.py(该文件可以为空,但在Python 3.3及以后的版本中,如果包目录下存在__pycache__或nspkg.pth文件,或者该目录是namespace package,则可以省略__init__.py文件)
9 文件操作
在Python中进行文件读写操作的步骤:
step1:打开文件:open(file, mode, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- file:
- 类型:
str
、bytes
或os.PathLike
对象。 - 说明:这是要打开的文件的路径(相对路径或绝对路径)或文件名。
- 类型:
- mode(可选):
- 类型:
str
。 - 默认值:
'r'
(读取模式)。 - 说明:文件的打开模式。常见的模式有:
'r'
:读取模式(默认)。'w'
:写入模式,会覆盖文件。'x'
:创建模式,用于新建文件,如果文件已存在则会引发异常。'a'
:追加模式,数据会被写入到文件末尾。'b'
:二进制模式。't'
:文本模式(默认,与'b'
相对)。'+'
:更新模式(读取和写入)。
- 模式可以组合使用,如
'rb'
表示以二进制模式读取文件。
- 类型:
- buffering(可选):
- 类型:
int
。 - 默认值:
-1
。 - 说明:设置缓冲策略。-1 表示使用默认策略,0 表示不进行缓冲,1 表示行缓冲,大于 1 的整数值则表示缓冲区的大小(以字节为单位)。
- 类型:
- encoding(可选):
- 类型:
str
。 - 默认值:
None
,表示使用系统默认编码。 - 说明:用于文本文件的编码方式,如
'utf-8'
。
- 类型:
- errors(可选):
- 类型:
str
。 - 默认值:
None
,表示使用默认的错误处理策略。 - 说明:如何处理编码和解码错误。常见的选项有
'ignore'
、'replace'
等。
- 类型:
- newline(可选):
- 类型:
str
。 - 默认值:
None
,表示使用系统默认的新行符。 - 说明:控制文本模式中的新行符处理。可以是
None
、''
、'\n'
、'\r'
、'\r\n'
等。
- 类型:
- closefd(可选):
- 类型:
bool
。 - 默认值:
True
。 - 说明:如果为
False
,则当传递的file
不是文件名时(例如是文件描述符或类似文件的对象),文件描述符不会被关闭。这在某些特定的Unix环境或库中有用。
- 类型:
- opener(可选):
- 类型:
callable
。 - 默认值:
None
。 - 说明:一个自定义的打开器。它必须接受一个
file
参数,并返回一个打开的文件对象。这通常用于定制文件打开行为,例如在使用不同的文件系统或库时。
- 类型:
step2:读取或者写入文件内容
一、读
① read()
方法:在只读模式下,read()
可以读取整个文件内容。
f = open('test.txt', 'r')
content = f.read()
print(content)
f.close()
- 如果文件很大,一次性读取可能会占用大量内存。此时可以使用
readline()
方法。
② readline()
方法:每次读取一行内容。
f = open('test.txt', 'r',)
line = f.readline()
while line:print(line.strip())line = f.readline()
f.close()
③ readlines()
方法:读取所有行并返回一个列表,列表中的每个元素是一行内容。
二、写
write()
方法:在写入或追加模式下,可以使用write()
方法写入内容。
f = open('test.txt', 'w')
f.write('Hello, World!')
f.close()
step3:关闭文件
close()
方法:在完成文件操作后,应该关闭文件以释放资源。也可以使用with
语句来自动管理文件的打开和关闭。
with open('test.txt', 'r') as f:content = f.read()print(content)
# 文件在这里自动关闭,不需要显式调用f.close()
10 类与对象
类和对象是面向对象编程(OOP)的核心概念,对象是由类实例化而来的,而类则定义了对象的属性和行为。
10.1 类与对象
类是一个模板,描述了具有相同属性和方法的对象的集合。通过类可以创建具有特定行为(方法)和特征(属性)的对象。
类的三大特点:封装、继承、多态。
- 封装:类将属性和方法封装起来,外部不可见,只有通过类提供的接口才能与对象进行信息交换。这种机制保护了对象的数据,防止了外部直接访问对象的内部状态。
- 继承:类可以由已有的类派生,派生出来的类拥有父类的方法和属性。这使得代码更容易复用和扩展。
- 多态:同一个方法可以处理不同类型的参数,类可以根据不同的参数类型调用不同的方法,增加了代码的灵活性和可扩展性。
在Python中,使用class
关键字来定义类,类通常包含类名、类的属性、类的方法,类名通常首字母大写:
class Animal:variable = "我是类属性" ## 类属性,所有实例都可使用#初始化,实例化这个类时的时候最先的入口,这里面的参数都是在实例化的时候传入的#类的构造器,用于在创建对象时初始化对象的属性def __init__(self, name, species):self.name = name #self.name代表实例化属性self.species = speciesdef make_sound(self):print(f"{self.name}是一只{self.species},他会叫")def move(self):print("动物会跑")# 创建Animal类的一个实例
dog = Animal("土豆","狗")
dog.make_sound() #输出:土豆是一只狗,他会叫
dog.move()#输出:动物会跑
print(dog.variable) # 输出:我是类属性cat = Animal("花花","猫")
cat.make_sound() #输出:花花是一只猫,他会叫
10.2 类中的属性
属性主要分为两类:类属性和实例属性。
class Animal:variable = "我是类属性" # 类属性,所有实例都可使用#初始化,实例化这个类时的时候最先的入口,这里面的参数都是在实例化的时候传入的def __init__(self, name, species):self.name = name #self.name代表实例化属性self.species = speciesdog = Animal("土豆","狗")
cat = Animal("花花","猫")
print(dog.variable) # 输出:我是类属性
print(cat.variable) # 输出:我是类属性Animal.variable = "类属性被修改了"
print(dog.variable) # 输出:类属性被修改了
print(cat.variable) # 输出:类属性被修改了
**① 类属性:**绑定到类本身上的属性,被类的所有实例共享,修改类属性会影响到类的所有实例。
- 访问类属性:可以通过类名访问,如
Animal.variable
,也可以通过实例对象访问(不推荐,可能会与同名实例属性混淆)。通过实例访问属性时,如果实例没有该属性,Python会查找类属性。如果类也没有该属性,则会抛出AttributeError
异常。 - 修改属性:直接对属性赋值。
**② 实例属性:**是绑定到类实例(即对象)上的属性。每个实例都有自己的属性副本,这些属性在实例之间是相互独立的。实例属性通常在实例的构造器方法(__init__
)中初始化。
访问实例属性:通过实例对象访问,如cat.name
。在类中定义方法时,第一个参数通常是self
,它代表类的实例本身。通过self
可以访问实例属性和其他方法。
私有属性和公有属性:
class Person:def __init__(self, name, age):self.name = name # 公有属性,外部可以直接访问self.__age = age # 私有属性,外部无法直接访问,只能在类内部使用def set_age(self, age):self.__age = age # 设置私有属性的值def get_age(self):print(self.__age) # 打印私有属性的值p = Person("团团", 6)
print(p.name) # 输出: 团团
p.get_age() # 输出: 6
p.set_age(10)
p.get_age() # 输出: 10
print(p.__age) # 尝试直接访问私有属性,会抛出 AttributeError 异常
10.3 类中的公有和私有方法
class Person:def __init__(self, name, age):self.name = name # 公有属性self.__age = age # 私有属性,只能在内中调用#公有方法名称前面加__,就变成私有方法了def __show_age(self):print(f"{self.name}今年{self.__age}岁了")# 在类外部,不能直接访问私有方法,但是可以在类内部定义一个公有方法,间接访问def display_age(self):self.__show_age()p = Person("团团", 6)
p.display_age()
10.4 继承
继承是一种面向对象编程(OOP)的特性,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。通过继承,子类可以重用父类中定义的代码,同时添加或覆盖特定的功能。
**① 单继承:**一个子类只继承一个父类。
#定义父类,父类通常包含一些通用的属性和方法,可以在子类中直接使用
class Animal:def __init__(self, name):self.name = namedef speak(self):print("动物都会叫")def run(self):print("动物都会跑")#子类Dog继承Animal类,Dog类可以定义自己的属性和方法,也可以覆盖父类中的方法。
class Dog(Animal):def speak(self):#如果子类需要扩展父类的方法而不是完全覆盖它,可以使用super()函数来调用父类的方法。super().speak()#子类可以直接访问父类的公有属性和方法,如果父类有私有属性(以双下划线开头),# 子类不能直接访问它们,但可以通过父类提供的公有方法来间接访问print(f"{self.name} 汪汪叫!")class Cat(Animal):#子类可以定义与父类同名的方法来覆盖父类的方法。这是多态的一种形式,允许子类根据需要提供特定的实现。def run(self):print(f"{self.name}会跑")d = Dog("皮皮")
c = Cat("咪咪")#调用Dog实例的run方法,会调用继承自Animal的run
d.run() # 输出: 动物都会跑# 调用Dog实例的speak方法,会先调用父类的speak方法,然后再打印Dog特有的叫声
d.speak() #输出:动物都会叫#输出:皮皮 汪汪叫!#会调用Cat覆盖的run方法
c.run()#输出:咪咪会跑
② 多继承:指一个子类继承多个父类的情况。
# 定义驴类
class Donkey:def __init__(self, name):self.name = nameself.load_capacity = 150 # 驴的负载能力def speak(self):return f"{self.name} 在啊——呃——啊——呃的叫"# 定义马类
class Horse:def __init__(self, name):self.name = nameself.speed = 50 # 马的速度def speak(self):return f"{self.name} 在昂昂叫"# 定义骡子类,继承自驴类和马类
class Mule(Donkey, Horse):def __init__(self,name):super().__init__(name) # 注意:这里super()只会调用第一个父类的__init__方法# 由于Python不支持真正的多重__init__调用,我们需要手动设置速度属性self.speed = 40 # 假设骡子的速度介于驴和马之间# 如果需要覆盖或扩展父类的方法,可以在这里定义# 例如,我们可以定义一个特殊的speak方法来结合驴和马的声音def speak(self):donkey_speak = super().speak() # 调用驴类的speak方法(实际上是第一个父类的)horse_speak = Horse.speak(self) # 直接调用马类的speak方法,因为super()不会自动遍历到第二个父类return f"{self.name} 会这样子叫: {donkey_speak} and {horse_speak}"# 创建骡子实例
mule = Mule("Muley")# 使用继承的属性和方法
print(f"{mule.name} 可以拉 {mule.load_capacity} kg的货物")
print(f"{mule.name} 可以以 {mule.speed} km/h的速度奔跑")
print(mule.speak())