Python快速入门
一、Python基础语法
1. 字面量
字面量:在代码中,被写下来的的固定的值,称之为字面量
类型 | 描述 | 说明 |
---|---|---|
数字(Number) | 整数(int) 浮点数(float) 复数(complex) 布尔(bool) | - 整数(int),如:10、-10 - 浮点数(float),如:13.14、-13.14 - 复数(complex),如:4+3j,以j结尾表示复数 - 布尔(bool)True表示真,False表示假。True本质上是数字1,False是0 |
字符串(String) | 描述文本的一种数据类型 | 字符串(string)由任意数量的字符组成 |
列表(List) | 有序的可变序列 | Python中使用最频繁的数据类型,可有序记录一堆数据 |
元组(Tuple) | 有序的不可变序列 | 可有序记录一堆不可变的Python数据集合 |
集合(Set) | 无序不重复集合 | 可无序记录一堆不重复的Python数据集合 |
字典(Dictionary) | 无序Key-Value集合 | 可无序记录一堆Key-Value型的Python数据集合 |
2. 注释
注释是代码中的解释型语句,用来对代码内容进行注解注释不是代码,不会被程序执行
-
单行注释
# 单行注释
-
多行注释
""" 多行注释 可以换行 author:一条代码狗 """
3. 变量
变量就是在程序运行时,记录数据用的
定义格式:变量名 = 变量值
特征 :变量的值可以改变
num = 20
4. 数据类型
数据类型包括字面量表格中的那些
-
验证数据类型使用type()方法
# 查看变量中存储的数据的类型 type(变量名)
5. 数据类型转换
语句(函数) | 说明 |
---|---|
int(x) | 将x转换为一个整数 |
float(x) | 将x转换为一个浮点数 |
str(x) | 将对象 x 转换为字符串 |
-
任何类型,都可以通过str(),转换成字符串
-
字符串内必须真的是数字,才可以将字符串转换为数字
6. 标识符
标识符:是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名。
标识符命名中,只允许出现:英文中文数字下划线(_)
不推荐使用中文
数字不可以开头
- 变量的命名规范
- 见名知意
- 下划线命名法
- 英文字母全小写
7. 运算符
-
算数运算符
运算符 描述 实例 + 加 两个对象相加 a + b 输出结果 30 - 减 得到负数或是一个数减去另一个数 a - b 输出结果 -10 * 乘 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200 / 除 b / a 输出结果 2 // 取整除 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 % 取余 返回除法的余数 b % a 输出结果 0 ** 指数 a**b 为10的20次方, 输出结果 100000000000000000000 -
赋值运算符和复合赋值运算符
运算符 描述 实例 = 赋值运算符 把 = 号右边的结果 赋给 左边的变量,如 num = 1 + 2 * 3,结果num的值为7 += 加法赋值运算符 c += a 等效于 c = c + a -= 减法赋值运算符 c -= a 等效于 c = c - a *= 乘法赋值运算符 c *= a 等效于 c = c * a /= 除法赋值运算符 c /= a 等效于 c = c / a %= 取模赋值运算符 c %= a 等效于 c = c % a **= 幂赋值运算符 c **= a 等效于 c = c ** a //= 取整除赋值运算符 c //= a 等效于 c = c // a
8. 字符串
-
字符串的多中定义方式
-
单引号定义法
-
双引号定义法
-
三引号定义法
-
-
定义的字符串本身,是包含:单引号、双引号自身
- 单引号定义法,可以内含双引号
- 双引号定义法,可以内含单引号
- 可以使用转移字符(\)来将引号解除效用,变成普通字符串
-
字符串拼接
- 使用“+”号连接字符串变量或字符串字面量即可
- 无法和非字符串类型进行拼接(可以先类型转换,所有类型的数据都能转换为字符串)
-
字符串格式化(使用占位符)
# 字符串格式化:占位形式拼接字符串 # %s 内容转化为字符串放在占位位置 # %d 内容转化为整数放在占位位置 # %f 内容转化为浮点数放在占位位置 # "%d %s %f" % ( a , b , c ) print("字符串格式化:占位形式拼接字符串") age = 28 avg_salary = 16581.5 career = "Python工程师" msg = "我今年%d岁,%s,平均月薪%.2f" % (age, career, avg_salary) print(msg)
-
常用的占位符
- 字符串: %s
- 整数: %d
- 浮点数: %f
-
数字精度的控制(类似于C语言)
我们可以使用辅助符号"m.n"来控制数据的宽度和精度
- m,控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效.
- n,控制小数点精度,要求是数字,会进行小数的四舍五入
- 示例:
- %5d:表示将整数的宽度控制在5位,如数字11,被设置为5d,就会变成:[空格][空格][空格]11,用三个空格补足宽度。
- %5.2f:表示将宽度控制为5,将小数点精度设置为2,小数点和小数部分也算入宽度计算。如,对11.345设置了%7.2f 后,结果是:[空格][空格]11.35。2个空格补足宽度,小数部分限制2位精度后,四舍五入为 .35
- %.2f:表示不限制宽度,只设置小数点精度为2,如11.345设置%.2f后,结果是11.35
-
-
字符串格式化(快速写法)
这种写法不做精度控制,也不理会类型 ,适用于快速格式化字符串
语法:
# 字符串格式化-快速写法 # f"{变量}{变量}" # 不做精度控制 print("字符串格式-快速写法") age = 28 num = 1 career = "Python工程师" avg_salary = 16581.5 msg = f"我今年{age+num}岁,{career},平均月薪{avg_salary}" print(msg)
9. 数据输入
input()语句的功能是,获取键盘输入的数据
可以使用:input(提示信息),用以在使用者输入内容之前显示提示信息。
要注意,无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型
二、Python 判断语句
1. 语法
if的基本使用语法 if 要判断的条件: 条件成立时,要做的事情 elif 要判断的条件: 条件成立时,要做的事情 else: 条件不成立时执行 注意事项 条件后的':'不能忘记写, 归属于if或else if或else的代码块,前方要填充四个空格缩进 嵌套判断语句,一定要注意空格缩进,Python中通过缩进判断层次关系
2. 案例
# 案例
# 1.数字随机产生0-10
# 2.有三次机会猜测数字通过三层嵌套实现
# 3.每次猜不中,会提示大了或小了
import random
num = random.randint(1, 10)
num_cai = int(input('请您猜测并输入num的值:'))
if num_cai == num:
print(f'恭喜您猜对了数字{num}')
else:
if num_cai > num:
print('大了')
else:
print('小了')
num_cai = int(input('请您猜测并输入num的值:'))
if num_cai == num:
print(f'恭喜您猜对了数字{num}')
else:
if num_cai > num:
print('大了')
else:
print('小了')
num_cai = int(input('请您猜测并输入num的值:'))
if num_cai == num:
print(f'恭喜您猜对了数字{num}')
else:
print(f'您三次都错了数字num是{num}')
三、Python循环语句
1. while循环
-
语法
while语法 条件类型为布尔类型 空格缩进不能忘
while conditions :
条件满足时,Todo1
条件满足时,Todo2
条件满足时,Todo3-
案例
# 九九乘法表 i = 1 j = 1 while i <= 9: while j <= i: print(f'{j}*{i}={i * j}', end=' ') j += 1 print() i += 1 j = 1
-
2. for循环
for循环也被称之为:遍历循环
Python的for循环无法构建无限循环(被处理的数据集不可能无限大)
-
for循环之遍历循环
语法:
for 临时变量 in 待处理数据集: 循环满足条件时执行的代码
-
注意:与C语言的for( ; ; )有区别
-
无法定义循环条件,只能被动取出数据处理要注意,
-
循环内的语句,需要有空格缩进
案例:
str1 = 'xzq' for x in str1: # 将str1中的内容一个一个取出赋予x临时变量 可以在循环体对x进行处理 print(x) print(str1)
-
-
for循环之range语句语法
语法:
range(num): 获取一个从0开始,到num结束的数字序列(不包含num) range(num1,num2): 获取一个从num1开始,到num2结束的数字序列(不包含num2) range(num1,num2,step): 获取一个从num1开始,到num2结束的数字序列(不包含num2)步长为Step # range(5,10,2)结果:[5,7,9]
案例:
# 九九乘法表 for x in range(1, 10): for y in range(1, x + 1): print(f'{y}*{x}={y * x}', end=" ") print()
3. continue与Break
continue的作用是:
中断所在循环的的本次执行,直接进入下一次break的作用是:
跳出整个循环,直接结束所在的循环
四、Python函数
- 函数必须先定义后使用
- 参数、返回值可以省略
- 无返回值默认返回值为:None 表示空的,无实际意义的意思,等同于判断中的False
1. 语法
def 函数名(传入参数):
函数体
return 返回值
2. 局部变量和全局变量
-
局部变量
在函数内定义的的变量,外部禁止访问
def test_a(): num = 100 # 局部变量 print(num)
-
全局变量
- 在函数外部定义的变量
- 函数里面使用global关键字定义的变量
def test_c(): global num1 # 声明a是全局变量 num1 = 101 print(num1)
五、Python数据容器
一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。
数据容器根据特点的不同,如:
是否支持重复元素
是否可以修改
是否有序,
等分为5类,分别是:列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
1. list(列表)
列表内的每一个数据,称之为元素
以 [] 作为标识
列表内每一个元素之间用, 逗号隔开
注意:列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套
-
基本语法:
字面量 [元素1,元素2,元素3,....] 定义变量 变量名称 = [元素1,元素2,元素3,....] 定义空变量 变量名称 = [] 或 变量名称 = list() 取出数据:列表的下标索引 正数:从零开始 负数:从-1开始 (最后一个开始) 不能超出范围,否则报错 my_list = [[1, 2, 3], [4, 5], 'xzq'] print(my_list[-1][1]) # 最后一个元素的第二个索引值
-
常用的操作
总览:编号 使用方式 作用 1 列表.append(元素) 向列表中追加一个元素 2 列表.extend(容器) 将数据容器的内容依次取出,追加到列表尾部 3 列表.insert(下标, 元素) 在指定下标处,插入指定的元素 4 del 列表[下标] 删除列表指定下标元素 5 列表.pop(下标) 删除列表指定下标元素 6 列表.remove(元素) 从前向后,删除此元素第一个匹配项 7 列表.clear() 清空列表 8 列表.count(元素) 统计此元素在列表中出现的次数 9 列表.index(元素) 查找指定元素在列表的下标找不到报错ValueError 10 len(列表) 统计容器内有多少元素 代码:
my_list = [1, 2, 3, 4, 5, 6] # 查找某元素的下标 # 功能:查找指定元素在列表的下标,如果找不到,报错ValueError # 语法:列表.index(元素) print(my_list.index(4)) # 3 """ 修改特定位置(索引)的元素值: 语法:列表[下标] = 值 """ my_list[0] = 10 # [10, 99, 2, 3, 4, 5, 6] print(my_list) """ 插入元素: 语法:列表.insert(下标, 元素),在指定的下标位置,插入指定的元素 """ my_list.insert(1, 99) print(my_list) # [10, 99, 2, 3, 4, 5, 6] """ 追加元素: 语法:列表.append(元素),将指定元素,追加到列表的尾部 """ my_list.append('xzq') print(my_list) # [10, 99, 2, 3, 4, 5, 6,'xzq'] """ 追加元素方式2: 语法:列表.extend(其它数据容器),将其它数据容器的内容取出,依次追加到列表尾部 """ my_list2 = ['xxx', 'yyy', 'zzz'] my_list.extend(my_list2) print(my_list) # [10, 99, 2, 3, 4, 5, 6, 'xzq', 'xxx', 'yyy', 'zzz'] """ 删除元素: 语法1: del 列表[下标] 语法2:列表.pop(下标) //返回值为移除的元素 """ my_list2 = ['xxx', 'yyy', 'zzz'] del my_list2[1] print(my_list2) # ['yyy', 'zzz'] my_list2 = ['xxx', 'yyy', 'zzz'] x = my_list2.pop(1) print(x) print(my_list2) # ['yyy', 'zzz'] """ 删除某元素在列表中的第一个匹配项 语法:列表.remove(元素) """ my_list2 = ['xxx', 'yyy', 'zzz'] my_list2.remove('zzz') print(my_list2) # ['xxx', 'yyy'] # 清空列表内容,语法:列表.clear() my_list2 = ['xxx', 'yyy', 'zzz'] my_list2.clear() print(my_list2) # [] # 列表.count(元素) 统计此元素在列表中出现的次数 my_list3 = [1, 2, 3, 6, 1, 5, 6, 2, 4] print(my_list3.count(1)) # 2 """ 统计列表内,有多少元素 语法:len(列表) """ my_list3 = [1, 2, 3, 6, 1, 5, 6, 2, 4] my_list = [[1, 2, 3], [4, 5], 'xzq'] print(len(my_list3)) # 9 print(len(my_list)) # 3
-
列表的特点:
- 可以容纳多个元素(上限为2**63-1、9223372036854775807个)
- 可以容纳不同类型的元素(混装)
- 数据是有序存储的(有下标序号)
- 允许重复数据存在
- 可以修改(增加或删除元素等)
-
遍历
使用while或者for都行
2. tuple(元组)
如果想要传递的信息,不被篡改,列表就不合
元组一旦定义完成,就不可修改了。所以,当我们需要在程序内封装数据,又不希望封装的数据被篡改,那么元组就非常合适了
-
语法
-
定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
-
注意:元组只有一个数据,这个数据后面要添加逗号,必须带逗号,否则不属于元组
-
元组也支持嵌套,支持下标索引
-
注意:
-
不可以修改元组的内容,否则会直接报错
-
可以修改元组内的list的内容(修改元素、增加、删除、反转等),不可以替换list为其它list或其它类型
#定义元组字面量 (元素,元素,......,元素) #定义元组变量 变量名称=(元素,元素,......,元素) #定义空元组 变量名称=() # 方式1 变量名称= tuple() # 方式2
-
-
常用的操作
编号 方法 作用 1 index() 查找某个数据,如果数据存在返回对应的下标,否则报错 2 count() 统计某个数据在当前元组出现的次数 3 len(元组) 统计元组内的元素个数 -
代码
t1 = (1, 2, 'xzq') print(t1) # (1,2,'xzq') # 非元组 t2 = (1) print(type(t2)) # int # 元组 t2 = (1,) print(type(t2)) # tuple t3 = ((1, 2, 3), ('one', 'two', 'three')) print(t3[1][2]) print(t3.index((1, 2, 3))) # 0 t4 = (1, 1, 1, 2, 3, 5) print(t4.count(1)) # 3 print(len(t4)) # 6 t5 = (1, 2, 3, [4, 5, 6]) # t4[0] = 6 报错 t5[3][0] = 8 print(t5)
-
元组的特点
- 可以容纳多个数据
- 可以容纳不同类型的数据(混装)
- 数据是有序存储的(下标索引)
- 允许重复数据存在
- 不可以修改(增加或删除元素等)
- 支持for循环
- 多数特性和list一致,不同点在于不可修改的特性。
3. str(字符串)
同元组一样,字符串是无法修改的数据容器
如果必须要修改,则只能的到一个新的字符串,旧的字符串是无法修改的
-
常用的操作
编号 操作 说明 1 字符串[下标] 根据下标索引取出特定位置字符 2 字符串.index(字符串) 查找给定字符的第一个匹配项的下标 3 字符串.replace(字符串1, 字符串2) 将字符串内的全部字符串1,替换为字符串2不会修改原字符串,而是得到一个新的 4 字符串.split(字符串) 按照给定字符串,对字符串进行分隔不会修改原字符串,而是得到一个新的列表 5 字符串.strip()字符串.strip(字符串) 移除首尾的空格和换行符或指定字符串 6 字符串.count(字符串) 统计字符串内某字符串的出现次数 7 len(字符串) 统计字符串的字符个数 -
代码:
my_str = 'xzq0723 skd master' # 索引取值 print((my_str[2])) # q print((my_str[-2])) # e # 查找子串的位置 print(my_str.index('skd')) # 8 """字符串的替换 语法:字符串.replace(字符串1,字符串2) 功能:将字符串内的全部:字符串1,替换为字符串2 注意:不是修改字符串本身,而是得到了一个新字符串哦 """ new_str = my_str.replace('s', '88') print(new_str) # xzq0723 88kd ma88ter """字符串的分割 语法:字符串.split(分隔符字符串) 功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中 注意:字符串本身不变,而是得到了一个列表对象 """ my_str = "x z q 0 7 2 3" str_arr = my_str.split(" ") print(str_arr) # ['x', 'z', 'q', '0', '7', '2', '3'] """ 字符串的规整操作(去""前后""空格) 语法:字符串.strip() 字符串的规整操作(去""前后""指定字符集) 语法:字符串.strip(字符串) """ my_str = "eh xzq0723 hello" print(my_str.strip()) # xzq0723 hello # 去除 含首尾 'h' 'e' 'l' 'o' print(my_str.strip('hello')) # [空格][空格][空格]xzq0723[空格][空格][空格][空格] my_str = "112xzq072321" # 去除 含首尾 3 1 2 print(my_str.strip('312')) # xzq07 """统计字符串中某字符串的出现次数 语法:字符串.count(字符串) """ my_str = "xzq0723xzq" print(my_str.count('xzq')) # 2 print(len(my_str)) # 10
-
字符串特点
基本和列表、元组相同
不同与列表和元组的在于:字符串容器可以容纳的类型是单一的,只能是字符串类型。不同于列表,相同于元组的在于:字符串不可修改
- 作为数据容器,字符串有如下特点:
- 只可以存储字符串
- 长度任意(取决于内存大小)
- 支持下标索引
- 允许重复字符串存在
- 不可以修改(增加或删除元素等)
- 支持for循环
4. 序列及其切片
- 序列是指:内容连续、有序,可使用下标索引的一类数据容器。
- 列表、元组、字符串,均可以可以视为序列。
- 序列的典型特征就是:有序并可用下标索引,字符串、元组、列表均满足这个要求
- 切片:从一个序列中,取出一个子序列
-
语法:序列 [ 起始下标 : 结束下标 : 步长 ]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列
-
起始下标表示从何处开始,可以留空,留空视作从头开始
-
结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾
-
步长表示,依次取元素的间隔
- 步长1表示,一个个取元素(默认)
- 步长2表示,每次跳过1个元素取
- 步长N表示,每次跳过N-1个元素取
- 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
注意,此操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)
-
-
代码
my_list = [1, 2, 3, 4, 5] print(my_list[1:4]) # [2, 3, 4] # 起始不写表示从头开始 结尾不写表示到尾结束 步长不写默认为1 print(my_list[::2]) # [1, 3, 5] # 起始不写表示从头开始 结尾不写表示到尾结束 步长不写默认为1 print(my_list[:3:]) # [1, 2, 3] # 逆向执行 从倒数第一个开始切片 print(my_list[::-1]) # [5, 4, 3, 2, 1]
5. set(集合)
集合,最主要的特点就是:不支持元素的重复(自带去重功能)、并且内容无序,因为要对元素做去重处理,所以无法保证顺序和创建的时候一致
-
语法
#定义集合字面量 {元素,元素,......,元素} #定义集合变量 变量名称={元素,元素,......,元素} #定义空集合 变量名称= set()
-
常见的操作
编号 操作 说明 1 集合.add(元素) 集合内添加一个元素 2 集合.remove(元素) 移除集合内指定的元素 3 集合.pop() 从集合中随机取出一个元素 4 集合.clear() 将集合清空 5 集合1.difference(集合2) 得到一个新集合,原有的2个集合内容不变,集合1有而集合2没有的 6 集合1.difference_update(集合2) 在集合1中,删除集合2中存在的元素,集合1被修改,集合2不变 7 集合1.union(集合2) 得到1个新集合,内含2个集合的全部元素原有的2个集合内容不变 8 len(集合) 得到一个整数,记录了集合的元素数量 -
集合的特点
- 可以容纳多个数据
- 可以容纳不同类型的数据(混装)
- 数据是无序存储的(不支持下标索引)
- 不允许重复数据存在
- 可以修改(增加或删除元素等)
- 支持for循环
6. dict(字典)
- 使用{}存储原始,每一个元素是一个键值对
- 每一个键值对包含Key和Value(用冒号分隔)
- 键值对之间使用逗号分隔
- Key和Value可以是任意类型的数据(key不可为字典)
- Key不可重复,重复会对原有数据覆盖
-
语法
#定义字典字面量 {key: value,key: value,...... , key: value} #定义字典变量 my_dict = ikey: value, key: value,...... , key: value} # 定义空字典 my_dict = {} # 空字典定义方式1 my_dict = dict() # 空字典定义方式2 注意: 键值对的Key和Value可以是任意类型(Key不可为字典) 字典内Key不允许重复,重复添加等同于覆盖原有数据 字典不可用下标索引,而是通过Key检索Value
-
常用操作:注意:新增和更新元素的语法一致,如果Key不存在即新增,如果Key存在即更新(Key不可重复)
编号 操作 说明 1 字典[Key] 获取指定Key对应的Value值 2 字典[Key] = Value 添加或更新键值对 3 字典.pop(Key) 取出Key对应的Value并在字典内删除此Key的键值对 4 字典.clear() 清空字典 5 字典.keys() 获取字典的全部Key,可用于for循环遍历字典 6 len(字典) 计算字典内的元素数量
注意:新增和更新元素的语法一致,如果Key不存在即新增,如果Key存在即更新(Key不可重复)
7. 数据容器对比总结
数据容器可以从以下视角进行简单的分类:
是否支持下标索引
- 支持:列表、元组、字符串 - 序列类型
- 不支持:集合、字典 - 非序列类型
是否支持重复元素:
支持:列表、元组、字符串 - 序列类型
不支持:集合、字典 - 非序列类型
是否可以修改
- 支持:列表、集合、字典
- 不支持:元组、字符串
列表 | 元组 | 字符串 | 集合 | 字典 | |
---|---|---|---|---|---|
元素数量 | 支持多个 | 支持多个 | 支持多个 | 支持多个 | 支持多个 |
元素类型 | 任意 | 任意 | 仅字符 | 任意 | Key:Value Key:除字典外任意类型 Value:任意类型 |
下标索引 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
重复元素 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
可修改性 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
数据有序 | 是 | 是 | 是 | 否 | 否 |
使用场景 | 可修改、可重复的一批数据记录场景 | 不可修改、可重复的一批数据记录场景 | 一串字符的记录场景 | 不可重复的数据记录场景 | 以Key检索Value的数据记录场景 |
-
基于各类数据容器的特点,它们的应用场景如下:
- list(列表):一批数据,可修改、可重复的存储场景
- tuple(元组):一批数据,不可修改、可重复的存储场景
- str(字符串):一串字符串的存储场景
- set(集合):一批数据,去重存储场景
- dict(字典):一批数据,可用Key检索Value的存储场景
-
容器通用功能总结
功能 描述 通用for循环 遍历容器(字典是遍历key) max 容器内最大元素 min() 容器内最小元素 len() 容器元素个数 list() 转换为列表 tuple() 转换为元组 str() 转换为字符串 set() 转换为集合 sorted(序列, [reverse=True]) 排序,reverse=True表示降序,得到一个排好序的列表
六、Python函数进阶
1. 函数多返回值
- 按照返回值的顺序,写对应顺序的多个变量接收即可
- 变量之间用逗号隔开
- 支持不同类型的数据return
代码如下:
def return_data():
return 1, 'xzq', {"name": "xzq", "age": 19}
x, y, z = return_data()
print(x) # 1
print(y) # xzq
print(z) # {'name': 'xzq', 'age': 19}
2. 函数多种传参方式
-
位置参数
-
调用函数时根据函数定义的参数位置来传递参数
-
注意:传递的参数和定义的参数的顺序及个数必须一致
-
代码如下:
def user_info(name, age, sex): print(f'姓名:{name},年龄:{age},性别:{sex}') # 位置传参 user_info('xzq', 18, '男')
-
-
关键字参数
-
函数调用时通过“键=值”形式传递参数
-
注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
-
代码如下:
def user_info(name, age, gender): print(f"您的名字是: {name},年龄是: {age},性别是:{gender}") # 关键字传参 user_info(name="小明", age=20, gender="男") # 可以不按照固定顺序 user_info(age=20, gender="男", name="小明") # 可以和位置参数混用,位置参数必须在前,且匹配参数顺序 user_info("小明", age=20, gender="男")
-
-
缺省参数
-
缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
-
注意:函数调用时,如果为缺省参数传值则修改默认参数值, 否则使用这个默认值
-
默认参数必须写到后面
-
代码如下:
def user_info(name, age, gender='男')∶ print(f'您的名字是{name},年龄是{age},性别是{gender}') user_info('TOM', 20) user_info('Rose', 18, '女')
-
-
不定长参数
不定长参数也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景
-
位置传递
-
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递
-
代码如下:
def user_info(*args): print(args) # ( 'TOM' , ) user_info('TOM') # ( "TOM" , 18) user_info('TOM', 18)
-
-
关键字传递
-
参数是“键=值”形式的形式的情况下, 所有的“键=值”都会被kwargs接受, 同时会根据“键=值”组成字典.
-
代码如下:
def u_info(**kwargs): print(kwargs) # {'name': 'xzq', 'age': 19} u_info(name="xzq", age=19)
-
-
3. 匿名函数
-
语法:
lambda 参数:函数(一行代码)
-
无名称的匿名函数,只可临时使用一次。
-
传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数
-
函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
-
代码如下:
"""函数作为参数传递 1. 函数本身是可以作为参数,传入另一个函数中进行使用的。 2. 将函数传入的作用在于:传入计算逻辑,而非传入数据。 """ def test_func(compute): result = compute(1, 2) return result def compute(x, y): return x + y
七、Python文件操作
文件的操作步骤:
打开文件
读写文件
关闭文件
注意:可以只打开和关闭文件,不进行任何读写
1. open()打开函数
-
在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:
open(name, mode, encoding)
-
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
-
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。如果该文件不存在,创建新文件。 a 打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 -
encoding:编码格式(推荐使用UTF-8)
-
示例代码:
f = open('python.txt', 'r', encoding=”UTF-8) # encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定 # 注意:此时的`f`是`open`函数的文件对象
1. 文件的读取
-
操作汇总
操作 功能 文件对象 = open(file, mode, encoding) 打开文件获得文件对象 文件对象.read(num) 读取指定长度字节不指定num读取文件全部 文件对象.readline() 读取一行 文件对象.readlines() 读取全部行,得到列表 for line in 文件对象 for循环文件行,一次循环得到一行数据 文件对象.close() 关闭文件对象 with open() as f: 通过with open语法打开文件,可以自动关闭 -
代码如下:
for line in f: print(line, end="") f.close() # with open 语法 with open("test.txt", "r", encoding="UTF-8") as f: for line in f: print(line, end="")
2. 文件的写入
-
代码:
# 1. 打开文件 f = open('python.txt', 'w') # 2.文件写入 f.write('hello world') # 3. 内容刷新 f.flush()
- 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
- 当调用flush的时候,内容会真正写入文件
- 这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)
-
写操作注意
- 文件如果不存在,使用”w”模式,会创建新文件
- 文件如果存在,使用”w”模式,会将原有内容清空
- close()方法,带有flush()方法的功能
3. 文件的追加
和文件的写入基本一致,区别在于:
f = open('python.txt', 'a')
八、Python异常模块与包
1. 异常
当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”, 也就是我们常说的BUG
-
异常演示:
🐇:例如:以’r’模式打开一个不存在的文件
f = open('linux.txt', 'r')
结果:
-
异常的捕获
-
为什么要捕获异常?
当我们的程序遇到了BUG, 那么接下来有两种情况:
- ① 整个程序因为一个BUG停止运行
- ② 对BUG进行提醒, 整个程序继续运行
显然在之前的学习中, 我们所有的程序遇到BUG就会出现①的这种情况, 也就是整个程序直接奔溃.但是在真实工作中, 我们肯定不能因为一个小的BUG就让整个程序全部奔溃, 也就是我们希望的是达到②的这种情况那这里我们就需要使用到捕获异常
-
异常捕获的基本语法
try: print(name) except NameError as e: print('name变量名称未定义错误')
注意:
- ① 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
- ② 一般try下方只放一行尝试执行的代码。
-
捕获多个异常
当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。
try: print(1/0) except (NameError, ZeroDivisionError) as e: print('ZeroDivision错误...'+e)
-
捕获所有异常:所有异常都继承于Exception
try: print(name) except Exception as e: print(e)
-
异常else
else表示的是如果没有异常要执行的代码
try: print(1) except Exception as e: print(e) else: print('我是else,是没有异常的时候执行的代码')
结果:
-
异常的finally
finally表示的是无论是否异常都要执行的代码,例如关闭文件。
try: f = open('test.txt', 'r') except Exception as e: f = open('test.txt', 'w') else: print('没有异常,真开心') finally: f.close()
-
-
异常的传递性
- 当函数func01中发生异常, 并且没有捕获处理这个异常的时候, 异常会传递到函数func02, 当func02也没有捕获处理这个异常的时候main函数会捕获这个异常, 这就是异常的传递性.
- 提示: 当所有函数都没有捕获异常的时候, 程序就会报错
- 利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候, 就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都会传递到main函数中, 这样就可以确保所有的异常都会被捕获
2. 模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾. 模块能定义函数,类和变量,模块里也能包含可执行的代码.
-
模块的作用:模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用(导入模块去使用)
-
模块的导入方式
模块在使用前需要先导入
-
语法:[]表示可选
[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]
-
常用的组合
-
import 模块名
基本语法:
import 模块名 import 模块名1,模块名2 模块名.功能名()
案例:
# 导入时间模块 import time print("开始") # 让程序睡眠1秒(阻塞) time.sleep(1) print("结束")
-
from 模块名 import 类、变量、方法等
基本语法:
from 模块名 import 功能名 功能名()
案例:
# 导入时间模块中的sleep方法 from time import sleep print("开始") # 让程序睡眠1秒(阻塞) sleep(1) print("结束")
-
from 模块名 import *
基本语法:
from 模块名 import * 功能名()
案例:
# 导入时间模块中所有的方法 from time import * print("开始") # 让程序睡眠1秒(阻塞) sleep(1) print("结束")
-
import 模块名 as 模块别名
:as定义别名基本语法:
# 模块定义别名 import 模块名 as 模块别名
案例:
# 模块别名 import time as tt tt.sleep(2) print('hello')
-
from 模块名 import 功能名 as 功能别名
基本语法:
# 功能定义别名 from 模块名 import 功能 as 功能别名
案例:
# 功能别名 from time import sleep as sl sl(2) print('hello')
-
-
3. 自定义模块
Python中已经帮我们实现了很多的模块. 不过有时候我们需要一些个性化的模块, 这里就可以通过自定义模块实现, 也就是自己制作一个模块
-
如何自定义模块并导入?
在Python代码文件中正常写代码即可,通过import、from关键字和导入Python内置模块一样导入即可使用。
-
制作自定义模块
-
新建一个Python文件,命名为my_module1.py,并定义test函数
def test(a,b): print(a+b)
-
测试my_module1模块
# 导入自定义包 from my_module1 import test test(1,2)
-
注意:每个Python文件都可以作为一个模块,模块的名字就是文件的名字. 也就是说自定义模块名必须要符合标识符命名规则
-
-
在模块中测试功能
在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如,在my_module1.py文件中添加测试代码test(1,1)
-
my_module1模块代码
def test(a, b): print(a + b) test(1, 1)
-
问题: 此时,无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行
test
函数的调用 -
解决方案:
if (__name__ == "__main__")
表示,只有当程序是直接执行的才会进入if内部,如果是被导入的,则if无法进入def test(a, b): print(a + b) # 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行test函数调用 if __name__ == '__main__': test (1, 1)
-
-
注意事项:当导入多个模块的时候,且模块内有同名功能. 当调用这个同名功能的时候,调用到的是后面导入的模块的功能,即后面导入的覆盖前面的
-
__all__
如果一个模块文件中有
__all__
变量,当使用from xxx import *
导入时,只能导入这个列表中的元素__all__ = ['test'] def test(): print('test2') def test1(): print('test2')
4. 包
从物理上看,包就是一个文件夹,在该文件夹下包含了一个
__init__.py
文件,该文件夹可用于包含多个模块文件 从逻辑上看,包的本质依然是模块
package的定义很简单,在当面目录下有
__init__.py
文件的目录即为一个package。但是这会分为两种情况,第一种情况是一个空的
__init__.py
文件,另外一个情况是写了代码的__init__.py
文件。不管是空的还是有内容的,这个目录都会被认为是一个package,这是一个标识。
-
包的作用
当我们的模块文件越来越多时,包可以帮助我们管理这些模块, 包的作用就是包含多个模块,但包的本质依然是模块
-
建包快速入门
-
① 新建包
my_package
- 注意:新建包后,包内部会自动创建
__init__.py
文件,这个文件控制着包的导入行为
- 注意:新建包后,包内部会自动创建
-
② 新建包内模块:
my_module1
和my_module2
-
my_module1
print(1) def info_print1(): print('my_module1')
-
my_module2
print(2) def info_print1(): print('my_module2')
-
-
③
__init__.py
import my_module1 import my_module2
-
④ 包结构如下
-
-
导入包
一个package 被导入,不管在什么时候
__init__.py
的代码都只会被执行一次。
__init__.py
内的导入顺序:from package import something
import
语句会首先检查something
是不是__init__.py
的变量,然后检查是不是subpackage
,再检查是不是module
,最后抛出ImportError
,检查顺序如下:__init__.py
文件内变量- 是不是package内的
subpackage
- 是不是package内的
module
-
方式一:
import 包名.模块名 包名.模块名.目标
-
方式二:
__all__ = ["my_module2"]
-
注意:必须在
__init__.py
文件中添加__all__ = []
,控制允许导入的模块列表
__all__
针对的是 ’ from … import * ‘ 这种方式对 ‘ import xxx ’ 这种方式无效 -
在
from package import *
语句中,- 如果
__init__.py
中定义了__all__
魔法变量,那么在__all__
内的所有元素都会被作为模块自动被导入(ImportError
任然会出现,如果自动导入的模块不存在的话)。 - 如果
__init__.py
中没有__all__
变量,导出将按照以下规则执行:
- 此 package 被导入,并且执行
__init__.py
中可被执行的代码 __init__.py
中定义的 variable 被导入__init__.py
中被显式导入的 module 被导入
- 如果
-
-
第三方包
-
安装第三方包
pip install 包名称
-