一、python概述

Python 是一门解释型、面向对象、动态类型的高级编程语言,由荷兰程序员吉多・范罗苏姆(Guido van Rossum,又称 “龟叔”)于 1989 年构思,1991 年正式发布。它的核心设计理念是 “优雅、明确、简单”,致力于让开发者用更少的代码实现更强大的功能,如今已成为全球最流行的编程语言之一。

二、python注意事项

1.python以.py为扩展名,但不是必须的

2.python区分大小写

3.语句后面可以不加 ;号

4.字符串内容和数字用,号链接,不是+号

5.在python中,非0属性都为真,0属性(如:” “、())为假

6.在print(end = “”) 代表不换行

7.pass 占位符,在方法或函数中什么都不想写的时候使用,防报错

多行注释和单行注释:

1.# 单行注释

2.””” 内容 “”” 多行注释

3.’’’ 内容 ‘’’ 多行注释

三、基本变量

1.基本概述

无论哪种高级语言程序,变量都是其程序基本组成单位

变量有三个基本要素:类型 名称 值!!!!
python变量在使用的时候必须赋值!!!!!
查看类型的数据: type(object) 如: a =10 print(type(a)) #输出 <class “int”>!!!!
前面加上 f 也可以查询类型: print(f”hello 的类型是{type(“hello”)}”)
查看变量是多少字节:print(sys.getsizeof) 导入 import sys

id(变量名) 可以查询他的地址

1
2
3
4
5
6
7
8
9
a = 1
b = 3
b = 5
c = 10 ** 3 #python有幂运算
e = 11 ** 5
print(b,"类型是:",type(b))#输出5,将上面b的值覆盖了
print(f"7 的类型是{type(7)}")
print(sys.getsizeof((c)))
print(sys.getsizeof((e)))

2.数据类型

变量类型(数据类型) 具体说明 定义 / 标识 示例代码 核心特性 可变性
整型(int) 整数(正 / 负 / 零,无大小限制) 无特殊标识,直接书写整数 a = 10b = -5c = 0d = 1000000000000 1. 支持加减乘除、取模、幂运算等常见数值运算;2. Python 3 无long类型,所有整数统一为int;3. 支持二进制(0b开头)、八进制(0o开头)、十六进制(0x开头)表示 不可变
浮点型(float) 小数(含科学计数法表示) 带小数点,或科学计数法标识 a = 3.14b = -0.5c = 2.0d = 1e5(等价于 100000.0)、e = 2.3e-4(等价于 0.00023) 1. 基于二进制存储,存在精度误差(如0.1 + 0.2 ≠ 0.3);2. 支持所有数值运算,运算结果可能转为浮点型;3. 无穷大表示为float('inf'),非数字表示为float('nan') 不可变
布尔型(bool) 逻辑判断值(仅两种结果) True(真)/False(假) a = Trueb = Falsec = 10 > 5(结果为True)、d = (1 == 2)(结果为False 1. 本质是特殊整型(True等价于 1,False等价于 0),可参与数值运算;2. 用于条件判断(ifwhile)、逻辑运算(andornot);3. 非 0 数值、非空字符串等会被判定为True,0、空字符串、None会被判定为False 不可变
字符串(str) 字符序列(文本数据) 单 / 双 / 三引号包裹 a = "hello"b = 'Python'c = """多行字符串"""d = '123'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#1.数据类型
from decimal import Decimal
name = "chen" #字符串型
age = 20 #整数型
score = 97.4 #小数型
print(name,"\n",age,"\n",score)
print(9**88)#可以表示3500个长度的数字
#浮点数精度损失
print(8.1/3)#输出 2.666666666667
#精准输出
b = Decimal("8.1") / Decimal("3")
print(b)#输出 2.7

#布尔值 非0都是真值,0是假值
if 0:
print("Hh")
if 1.1:
print("heihei")

if "真的":
print("也会被输出")

#字符串
str = r"java\npython\tjs"
print(str)#此时输出 java\python\js 不会识别\n和\t



#3.加号的使用 类型不同会报错
name2 = "小"
age = 20
print(name2 + "陈")#字符串拼接 小陈
print("40" + "50")#4050
print(30.44 + 55)#85.44
#print("100" + 3)#报错 类型不同会报错!!!!!!

3.格式化输出

旧版: print(“%d”,变量名) 新版: print(f”{变量名}”) 或 printf(“{}”.format(变量名))

占位符 对应数据类型 核心说明 示例代码 运行结果
%d 整型(int) 格式化十进制整数,支持补零、指定宽度 print("数字:%d,补零到5位:%05d" % (123, 123)) 数字:123,补零到 5 位:00123
%f 浮点型(float) 格式化浮点数,默认保留 6 位小数,可指定小数位数 print("默认:%f,保留2位:%.2f" % (3.1415, 3.1415)) 默认:3.141500,保留 2 位:3.14
%s 所有类型(万能) 兼容字符串、整型、浮点型、布尔型等,自动转字符串 print("姓名:%s,年龄:%s,成绩:%s" % ("小美", 18, 95.5)) 姓名:小美,年龄:18,成绩:95.5
%x/%X 整型(int) 格式化十六进制整数,%x小写、%X大写(可选,高频用于进制转换场景) print("十六进制小写:%x,大写:%X" % (255, 255)) 十六进制小写:ff,大写:FF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
三、格式化输出
#1.规则:用%开头 %s表示string类型字符、%.2f表示小数点数、%d整数

name1 = "xiaochen"
age1 = 30
score1 = 40.4
geder = "男"
print("个人信息:%s-%d-%.2f-%s" %(name1,age1,score1,geder))

2.#format()函数
print("个人信息:{} {} {}" .format(name1,age1,score1))

3.#f-strings(推荐)
print("个人信息:{name1} {age1} {score1}" )

有这些方法任选其一

4.驻留机制

使用id()函数 查看变量的内存地址 python仅支持int string bool类型其他不可以!!!

str = “hello”

str2 = “hello”

str3 = “hello”

当不同的变量取相同类型和内容的值时,python不会在开辟新的空间存放相同的值,而是不同的变量指向一个值

如:str、str2、str3只会指向一个”hello”!!!!!!!!!!!

注:在控制台特殊情况:[-5,256]在控制台的变量超过这个数组数字时,字符串驻留机制会失效!!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#字符串驻留机制     使用id()函数
str = "hello"
str2 = "hello"
str3 = "hello"
#id()函数 三个值的地址都是一样的
print(id(str))
print(id(str2))
print(id(str3))

str4 = -6
str5 = -6
print(id(str4))
print(id(str5))

str6 = "#"
str7 = "#"
print(id(str6))
print(id(str7))

5.数据转换

在python中不同数据类型是不可以进行拼接的,这个问题如何解决?

1.隐式转换

在运算的时候低的数据类型会自动转向高的数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#隐式转换
a = 1
b = 1.1
c = "python"
print(type(a))#会自动转为int类型
print(type(b))#会自动转为float类型
print(type(c))#会自动转为string类型

d = 4
e = 8.5
print(d + e)#输出 12.5

f = 1
g = f + 0.5
print(g)#会转换为浮点数 输出1.5

2.显式转换 数据类型(变量名)

1
2
3
4
5
6
7
8
9
10
11
12
#显式转换
i = 10
#我要把 i 转化为 浮点数
j = float(i)
print(type(j),j)#10.0
#把 i 转化为 字符串型
k = str(i)
print(type(k),k)

#把 k 转化为 整数型
l = int(k)
print(type(l),l + 30)#输出40

四、运算符

1.算术符时表示一种特殊的运算符,用于表示数据的运算、赋值和比较

2.算数运算符

1
2
3
4
1.算数运算符
+ - * / % ** //
加、减、乘、除、取余、幂运算、取整除(向下取整)
注:取模公式:a % b = a-a // b*b

3.比较运算符

1
2
3
2.比较运算符
< > == != <= >= is isnot
is:判断两个变量引用对象是否为同一个 is not:与is相反

4.逻辑运算符

1
2
3
4
5
6
7
3.逻辑运算符
and or not
and: 与 X and Y 如果X为false,返回X,反之返回Y 如:10 and 20 返回20
or: 或 X or Y 如果X为true,返回X,反之返回Y 如:10 or 20 返回10
not: 非 not X 如果X为true,返回false;如果X为false,返回true 如:not 20 返回false

注:and优先级高于or,not最高!!!!!

5.赋值运算符

1
2
3
4.赋值运算符
= += -= *= /= %= //= **=
如:a *= b 和 a = a*b a **= b 和 a = a**b

6.三元运算符

1
2
5.三元运算符
语法:max = a if a > b else b

7.位运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
6.位运算符(难点)
原码、反码、补码
理解:
1.二进制的最高位是符号位:0是正数,1是负数
2.正数的原码、反码、补码都一样
3.负数的原码、反码、补码不一样(具体参考 位运算符.py)
4.0 的反码、补码都是 0
5.计算机运算的时候,都是以补码的方式进行运算,但结果是看它的原码!!!!!!!(重点)

>> << & ^ | ~
向右移两位、向左移两位、按位与、按位异或、按位或、按位取反

~: 对数据二进制数位补码取反,即把 1变成0,0变成1
&: 参与运算的两个值,如果两个相对应位都为1,该为结果就是1,反之为0 如:1101与1001 取反:1001
^: 参与运算的两个值,如果两个相对应位相异为1,该为结果就是1,反之为0 如:1101与1001 取反:0100
|:参与运算的两个值,如果两个相对应位有一个是1就为1,该位结果就是1,反之为0 如:1101与1001 取反:1101
<<: 左移诺干位,以右边的数指定移动位数,符号位不变,高位丢弃,低位补0 如:5<<1 5:0000 0101 取反:0000 1010
>>: 右移诺干位,以右边的数指定移动位数,低位溢出,符号位不变,并用符号位补溢出的高位
如:5 >> 1 0000 0101 = 5;高位加一位,低位最后一个扔掉 0000 0010 = 2

五、键盘输入和随机函数

1.键盘输入

变量名 = input()

注:input接收的都是字符串型!!!!

2.随机数

使用random模块里面的randint()函数随机生成数 导入 import random

语法:random.randint(a,b) 包含a和b

1
2
3
4
5
6
7
8
9
10
11
12
name = input("请输入名字:")
print(name)

#改变数据类型
age = int(input("请输入数字"))
print(type(age),age)
# ===========================
import random
#1.先导入random模块 import random
#2.变量 = random.randint(范围)
n = random.randint(1,100)
print(n)

六、流程控制

1.if语句

if 条件表达式:

需要运行代码块(内容)

elif:

需要运行代码块(内容2)

… 多个elif

else: 注:每个代码块需要有相同的代码块(tab 或 空格)

需要运行代码块(内容3) 最短的缩进对较长的缩进有包含关系,缩进前后没有要求

2.for循环

for 变量 in 范围/列表:

(需要循环的语句)

如果不用列表循环,可以用范围-内置函数range(start,stop,step = 1)(开始,停止,步长)

3.while循环

while 判断条件(为真执行):

(需要循环的语句)

else:

(执行的语句)

else配合break

4.match语句

match语句(python3.10版本以上才有)

和java的switch相似,但没有break;

语句:match (条件语句):

case 条件1:

输出

case 条件2:

输出

5.break

用于在for 和 while 语句当中,它会终结最近的外层循环,如果循环有可选的 else 语句,也会跳过该句子

6.continue

用于在for 和 while 语句当中,用于结束本次循环,继续下一个循环

7.return

return使用在函数,表示跳出当前函数

七、函数

1
2
3
4
5
6
7
8
9
10
1.为什么要函数?如果一个页面或其他页面需要执行很多相同或类似的方法,没有函数就会 代码累赘,不利于代码维护!
函数的好处:提高代码复用率、可以将代码封装,给用户进行调用
2.函数在某些特定的情况下也称 方法
3.在python中,有两种函数:系统函数和自定义函数
4.函数命名也遵循标识符命名规则
5.如果函数有相同名的,按就近原则调用(调用第二个)
6.如果形参和调用的实参数量不相同会报错,且形参和实参位置要对应
7.函数可以有多个返回值,类型不受影响
8.函数数值和字符串都有驻留机制!!!!!
9.内置函数:round(数字,保留小数点位数) 会四舍五入!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
二、系统函数和自定义函数
1.系统函数:


2.自定义函数:内置函数,模块,如数学函数math
(1)自定义函数语句:def 函数名():
(执行的代码)
return (要返回的值) (可有可无)

函数名() 调用.


(2)带参函数:def 函数名(参数一,参数二): 参数又叫 形参!
(执行的代码)
return (参数一或其他) (可有可无)
函数名(实参值) 调用.

注:使用return时,要在调用函数前面加一个 变量名,在print(变量名)。 如:变量名 = 函数名(实参值)


三、函数执行流程
1.函数的内容开始是放在 内存里代码区 里面的。
2.内存还会生成一个栈,栈里面有很多个栈,主栈 是调用函数的。
3.当调用函数时,会在栈生成一个 新栈,存放实参
4.内存又会生成 数据区,存放实参的值!
5.此时执行函数里面的代码,会将代码放到 新栈 里面
6.函数输出的结果放到 主栈 里面区!!!!
7.再将输出结果放到 控制台 里面!!


四、函数-递归机制
1.递归就是函数自己调用自己,每次调用会传不同的值,在代码加上调用函数就是
2.递归有助于编程者解决复杂问题,同时让代码更加简洁
3.递归必须向退出递归条件逼近,否则会无限递归


五、函数传递
1.将一个函数传递到另一个函数 就是 一个函数调用另一个函数
(具体查看函数作为参数传递.py)


六、匿名函数
1.如果有这样一个需求,函数作为参数进行传递,但这个函数只使用一次,这时可以考虑使用 lambda 匿名函数
2.格式: 变量名 = lambda 形参1,形参2: 函数体(一行代码)


七、局部变量和全局变量
全局变量:在整个程序范围内都可以访问,定义在函数外,拥有全局作用域的变量
局部变量:只能在声明的函数范围内访问,定义在函数内部,拥有局部作用域的变量

如:n1 = 22 #这个就是全局变量
def fn():
n2 = 33 #这个就是局部变量
print(n2)
print(n1) #函数内也可以访问 n1 这个变量!!!!
fn()
# print(n2) 无法访问到函数内的变量!!!!

注:如果全局变量和局部变量取名一样时,会根据就近原则去调用!!!!

如果全局变量和局部变量取名一样时,想让局部变量改为全局变量,则可以使用 glboal

八、数据容器

1.列表

Python 列表是有序、可变的容器类型.

格式: 列表名 = [元素,元素…] 遍历支持倒叙: -1是最后一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
list = [11,33,44,55,66,77]
print(type(list),list)
print(list[0])#下标0 是 11

#遍历列表
for i in range(len(list)):
print(list[i])


#统计10只鸡的体重
list1 = [22,44,6,7,9,11,3,5,6,7]

sum = 0
for j in range(len(list1)):
sum += list1[j]
print(sum / 10 )
print(sum)


#空列表
list3 = []
print(list3,type(list3))


#下标从 -1 开始
list4 = [11,55,66,"小陈学python"]
print(list4[-1])# 小陈学python
print(list4[-2])# 66

常用方法:

类别 方法 / 操作名称 核心语法 功能描述 示例代码 运行结果(基于初始列表 lst = [1, 2, 3, 2, 4]
元素添加相关 append() lst.append(元素) 在列表末尾添加单个元素(支持任意数据类型),直接修改原列表,无返回值 lst.append(5)``print(lst) [1, 2, 3, 2, 4, 5]
insert() lst.insert(索引, 元素) 在列表指定索引位置插入单个元素,索引超出范围则插入至末尾 / 开头,直接修改原列表,无返回值 lst.insert(2, 10)``print(lst) [1, 2, 10, 3, 2, 4]
extend() lst.extend(可迭代对象) 将可迭代对象(列表、元组、字符串等)的所有元素追加至列表末尾,直接修改原列表,无返回值 lst.extend([5, 6])``print(lst) [1, 2, 3, 2, 4, 5, 6]
元素移除相关 pop() lst.pop(索引)(索引可选,默认 - 1) 删除列表指定索引对应的元素,返回被删除的元素,直接修改原列表;默认删除末尾元素 deleted = lst.pop(3)``print(lst, deleted) [1, 2, 3, 4] 2
remove() lst.remove(元素值) 删除列表中第一个出现的指定元素值,直接修改原列表,无返回值;元素不存在则抛出ValueError lst.remove(2)``print(lst) [1, 3, 2, 4]
clear() lst.clear() 清空列表内所有元素,直接修改原列表,使其变为空列表,无返回值 lst.clear()``print(lst) []
元素调整相关 索引直接赋值 lst[索引] = 新元素 无专用方法,通过索引直接替换对应位置的元素,直接修改原列表 lst[1] = 20``print(lst) [1, 20, 3, 2, 4]
reverse() lst.reverse() 反转列表内元素的排列顺序,直接修改原列表,无返回值 lst.reverse()``print(lst) [4, 2, 3, 2, 1]
sort() lst.sort(key=None, reverse=False) 对列表元素进行排序,默认升序;key指定排序依据,reverse=True为降序,直接修改原列表,无返回值 lst.sort(reverse=True)``print(lst) [4, 3, 2, 2, 1]
元素查询与统计相关 index() lst.index(元素值, 起始索引, 结束索引) 查询指定元素值第一次出现的索引,可指定查询范围,返回对应索引值;元素不存在则抛出ValueError idx = lst.index(2)``print(idx) 1
count() lst.count(元素值) 统计指定元素值在列表中出现的总次数,返回非负整数;无该元素则返回 0 cnt = lst.count(2)``print(cnt) 2
in(成员运算符) 元素 in lst 判断指定元素是否存在于列表中,返回布尔值True/False,高频查询操作 print(2 in lst)``print(6 in lst) True``False
not in(成员运算符) 元素 not in lst 判断指定元素是否不存在于列表中,返回布尔值True/False,与in功能相反 print(6 not in lst)``print(2 not in lst) True``False
列表复制相关 copy() new_lst = lst.copy() 复制列表内容,返回一个与原列表内容一致的新列表(浅拷贝),不修改原列表 new_lst = lst.copy()``new_lst.append(5)``print(lst, new_lst) [1, 2, 3, 2, 4] [1, 2, 3, 2, 4, 5]
列表长度统计 len()(内置函数) len(lst) 统计列表的元素总个数(即列表长度),非列表专属但高频用于列表,返回正整数 length = len(lst)``print(length) 5
列表拼接与重复 +(拼接运算符) lst1 + lst2 将两个列表拼接为一个新列表,不修改原列表,返回新列表 lst2 = [5, 6]``print(lst + lst2) [1, 2, 3, 2, 4, 5, 6]
*(重复运算符) lst * n(n 为正整数) 将列表中的元素重复n次,生成一个新列表,不修改原列表,返回新列表 print(lst * 2) [1, 2, 3, 2, 4, 1, 2, 3, 2, 4]
列表转换与遍历辅助 join()(字符串方法,配合列表) "分隔符".join(lst_str) 字符串列表拼接为单个字符串,分隔符可选,返回新字符串;非字符串列表需先转换 lst_str = ["Python", "Java", "C++"]``print("-".join(lst_str)) Python-Java-C++

2.元组

Python 元组是有序、不可变的容器类型,其操作以 “查询、统计、辅助转换” 为主,无修改原元组的方法(因不可变特性)

格式: 元组名 = (元素,元素…) 注:如果是单个元素必须带逗号: tuple = (11,)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
tuple2 = (111,33,4455,666)
print(type(tuple2),tuple2)


#遍历元组
tuple1 = (11,44,55,66,77)
for i in tuple1:
print(i)


#空元组
k = ()
s = tuple()
print(type(k))
print(type(s))


#下标
tuple3 = (22,44,55,"python")
print(tuple3[3])
#tuple3[3] = "java" #此时会报错,不可以更改!!!!


#将列表作为元素
tuple4 = (22,3,66,77,[22,44,55,77,43])#包含列表
tuple4[4][2] = "python" #55变python
print(tuple4[4]) #[22,44,"python",77,43]

#单个元素后面加一个,号
tuple5 = (100,)
print(tuple5,type(tuple5))

常用方法:

元素查询与定位相关 索引取值 tup[索引] 通过索引获取对应位置的元素,索引支持正索引(从 0 开始)和负索引(从 - 1 开始) print(tup[2])``print(tup[-1]) 3``4
index() tup.index(元素值, 起始索引, 结束索引) 查询指定元素值第一次出现的索引,可指定查询范围,返回对应索引值;元素不存在则抛出ValueError idx = tup.index(2)``print(idx) 1
元素统计与判断相关 count() tup.count(元素值) 统计指定元素值在元组中出现的总次数,返回非负整数;无该元素则返回 0 cnt = tup.count(2)``print(cnt) 2
in(成员运算符) 元素 in tup 判断指定元素是否存在于元组中,返回布尔值True/False,高频查询操作 print(2 in tup)``print(6 in tup) True``False
not in(成员运算符) 元素 not in tup 判断指定元素是否不存在于元组中,返回布尔值True/False,与in功能相反 print(6 not in tup)``print(2 not in tup) True``False
元组长度与极值统计 len()(内置函数) len(tup) 统计元组的元素总个数(即元组长度),非元组专属但高频用于元组,返回正整数 length = len(tup)``print(length) 5
max()(内置函数) max(tup) 统计元组中元素的最大值,要求元组内元素类型可比较(如均为数值、均为字符串) print(max(tup)) 4
min()(内置函数) min(tup) 统计元组中元素的最小值,要求元组内元素类型可比较(如均为数值、均为字符串) print(min(tup)) 1
转换为列表 list(tup) 将元组转换为可变的列表,便于后续进行元素调整操作,返回新列表 lst = list(tup)``lst.append(5)``print(lst) [1, 2, 3, 2, 4, 5]
拼接为字符串(配合join() "分隔符".join(map(str, tup)) 先将元组内的元素转换为字符串类型,再拼接为单个字符串,返回新字符串 print("-".join(map(str, tup))) 1-2-3-2-4

3.字符串

Python 字符串是有序、不可变的字符序列,操作以 “查询、转换、拼接、处理” 为主,无修改原字符串的方法(因不可变特性,所有修改类操作均返回新字符串)。

1
2
3
4
5
6
7
8
9
10
11
print(ord("陈"))#38472		使用ord打印ASCLL码值
print(ord("a"))#97

#字符串索引值
s = "red-green"
print(s[2])


#字符串比较
print("tom" > "tt")#false
print("陈" > "刘")#True

常用方法:

字符查询与定位相关 索引取值 s[索引] 通过索引获取对应位置的字符,支持正索引(从 0 开始)和负索引(从 - 1 开始) print(s[6])``print(s[-3]) P / 1
index() s.index(子串, 起始索引, 结束索引) 查询子串第一次出现的起始索引,可指定查询范围,返回索引值;子串不存在抛出ValueError idx = s.index("Python")``print(idx) 6
rindex() s.rindex(子串, 起始索引, 结束索引) 从右往左查询子串第一次出现的起始索引,返回索引值;子串不存在抛出ValueError idx = s.rindex("l")``print(idx) 3
字符统计与判断相关 count() s.count(子串, 起始索引, 结束索引) 统计子串在字符串中出现的总次数,返回非负整数;无子串则返回 0 cnt = s.count("l")``print(cnt) 2
in(成员运算符) 子串 in s 判断子串是否存在于字符串中,返回布尔值True/False print("Python" in s)``print("Java" in s) True / False
not in(成员运算符) 子串 not in s 判断子串是否不存在于字符串中,返回布尔值True/False print("Java" not in s)``print("Python" not in s) True / False
len()(内置函数) len(s) 统计字符串的字符总个数(长度),非字符串专属但高频使用,返回正整数 length = len(s)``print(length) 15(含空格和数字)
字符串大小写转换相关 upper() s.upper() 将字符串中所有小写字母转为大写,返回新字符串,不修改原字符串 print(s.upper()) HELLO PYTHON 123
lower() s.lower() 将字符串中所有大写字母转为小写,返回新字符串,不修改原字符串 print(s.lower()) hello python 123
capitalize() s.capitalize() 将字符串首字符转为大写,其余字符转为小写,返回新字符串 print("hello PYTHON".capitalize()) Hello python
title() s.title() 将字符串中每个单词的首字符转为大写,其余转为小写,返回新字符串 print("hello python".title()) Hello Python
字符串去除空白 / 指定字符相关 strip() s.strip(指定字符) 去除字符串首尾的空白字符(默认)或指定字符,返回新字符串 print(" Hello Python ".strip())``print("###Python###".strip("#")) Hello Python / Python
lstrip() s.lstrip(指定字符) 去除字符串左侧的空白字符(默认)或指定字符,返回新字符串 print(" Hello Python ".lstrip()) Hello Python
rstrip() s.rstrip(指定字符) 去除字符串右侧的空白字符(默认)或指定字符,返回新字符串 print(" Hello Python ".rstrip()) Hello Python
字符串分割与拼接相关 split() s.split(分隔符, 最大分割次数) 以指定分隔符分割字符串,返回列表;默认以空白字符分割,最大分割次数可选 print(s.split())``print(s.split(" ", 1)) ['Hello', 'Python', '123'] / ['Hello', 'Python 123']
rsplit() s.rsplit(分隔符, 最大分割次数) 从右往左以指定分隔符分割字符串,返回列表;最大分割次数可选 print(s.rsplit(" ", 1)) ['Hello Python', '123']
join() "分隔符".join(可迭代对象) 将可迭代对象(字符串、列表等)中的元素用指定分隔符拼接,返回新字符串 lst = ["Hello", "Python", "123"]``print("-".join(lst)) Hello-Python-123
字符串替换与匹配相关 replace() s.replace(旧子串, 新子串, 替换次数) 将字符串中的旧子串替换为新子串,替换次数可选(默认全部替换),返回新字符串 print(s.replace("Python", "Java"))``print(s.replace("l", "L", 1)) Hello Java 123 / HeLlo Python 123
startswith() s.startswith(子串, 起始索引, 结束索引) 判断字符串是否以指定子串开头,返回布尔值True/False print(s.startswith("Hello"))``print(s.startswith("Python")) True / False
endswith() s.endswith(子串, 起始索引, 结束索引) 判断字符串是否以指定子串结尾,返回布尔值True/False print(s.endswith("123"))``print(s.endswith("Python")) True / False
字符串格式与判断类型相关 isdigit() s.isdigit() 判断字符串是否全部由数字组成,返回布尔值True/False print("123".isdigit())``print(s.isdigit()) True / False
isalpha() s.isalpha() 判断字符串是否全部由字母组成(无数字、空格等),返回布尔值True/False print("Python".isalpha())``print(s.isalpha()) True / False
isspace() s.isspace() 判断字符串是否全部由空白字符(空格、换行等)组成,返回布尔值True/False print(" ".isspace())``print(s.isspace()) True / False
字符串拼接与重复 +(拼接运算符) s1 + s2 将两个字符串拼接为一个新字符串,不修改原字符串,返回新字符串 s1 = "Hello"``s2 = "Python"``print(s1 + " " + s2) Hello Python

4.切片

Python 切片是一种高效截取有序可迭代对象(列表、元组、字符串等)部分元素的语法,无需循环即可快速获取指定范围的内容,返回一个与原对象类型一致的新对象(不修改原对象),核心适用于所有有序、可索引的容器类型。

格式: 容器名[起始索引:结束索引:步长] 支持负数查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
str = "hello,python"
#序列[1::1]
str_name1 = str[1::1]
print(str_name1)#ello,python 不取第一个下标


#序列[-1:-6:-1]
str_name2 = str[-1::-1]
print(str_name2)#nohtyp,olleh


#练习1 取前三个值和后三个值
list_name = ["kobe","jack","tom","hep","ssp","lisa"]
list_name1 = list_name[0:3:1]
print(list_name1)

list_name3 = list_name[-1:-4:-1]
list_name3.reverse()
print(list_name3)

5.集合

Python 集合是无序、不重复、可变的容器类型(另有不可变集合frozenset),核心特性是 “元素唯一性” 和 “支持数学集合运算”,操作以 “元素管理、集合间运算、判断校验” 为主.

格式: 集合名 = (元素,元素…) 创建空集合: 集合名 = set()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
set_one = {1000,33,44,55,66,77}
print(type(set_one),set_one)#结果与上面的顺序不一样 [33, 66, 55, 1000, 44, 77]


#去重
set_two = {"apple","apple","banana"}
print(set_two)#{'banana', 'apple'}


#无序,就是元素顺序和取出顺序不一致。集合底层会根据算法来存储和取数据,所以取出的数据顺序不变
set_stree = {100,22,33,44,55,66,77}
print(set_stree)
print(set_stree)#顺序一致


#遍历
set_four = {100,22,33,44,55,66,88}
for i in set_four:
print(i)


#空集合
set_five = set()

常用方法:

元素添加相关 add() s.add(元素) 向集合中添加单个元素,元素已存在则不执行任何操作,直接修改原集合 s.add(6)``print(s) {1, 2, 3, 4, 5, 6}
update() s.update(可迭代对象) 将可迭代对象中的所有元素批量添加到集合中,自动去重,直接修改原集合 s.update([6,7,8])``print(s) {1, 2, 3, 4, 5, 6, 7, 8}
元素移除相关 remove() s.remove(元素) 从集合中删除指定元素,元素不存在则抛出KeyError,直接修改原集合 s.remove(5)``print(s) {1, 2, 3, 4}
discard() s.discard(元素) 从集合中删除指定元素,元素不存在则不执行任何操作,直接修改原集合(比remove()更安全) s.discard(5)``s.discard(10)``print(s) {1, 2, 3, 4}(删除 10 无报错)
pop() s.pop() 随机删除并返回集合中的一个元素(因集合无序,无法指定索引),直接修改原集合;空集合调用抛出KeyError deleted = s.pop()``print(s, deleted) {2, 3, 4, 5} 1(删除结果随机,仅作示例)
clear() s.clear() 清空集合中所有元素,直接修改原集合,使其变为空集合 s.clear()``print(s) set()
元素判断与统计相关 in(成员运算符) 元素 in s 判断指定元素是否存在于集合中,返回布尔值True/False,因集合哈希存储,查询效率远高于列表 / 元组 print(3 in s)``print(10 in s) True / False
not in(成员运算符) 元素 not in s 判断指定元素是否不存在于集合中,返回布尔值True/False print(10 not in s)``print(3 not in s) True / False
len()(内置函数) len(s) 统计集合中元素的总个数(长度),非集合专属但高频使用,返回正整数 length = len(s)``print(length) 5
集合间数学运算相关 union() / ` `(并集) s.union(s2) / `s s2` 求两个集合的并集(包含所有在ss2中的元素),返回新集合,不修改原集合 `print(s.union(s2))``print(s s2)` {1, 2, 3, 4, 5, 6, 7, 8}(两种语法结果一致)
intersection() / &(交集) s.intersection(s2) / s & s2 求两个集合的交集(包含同时在ss2中的元素),返回新集合,不修改原集合 print(s.intersection(s2))``print(s & s2) {4, 5}(两种语法结果一致)
difference() / -(差集) s.difference(s2) / s - s2 求两个集合的差集(包含在s中但不在s2中的元素),返回新集合,不修改原集合 print(s.difference(s2))``print(s - s2) {1, 2, 3}(两种语法结果一致)
symmetric_difference() / ^(对称差集) s.symmetric_difference(s2) / s ^ s2 求两个集合的对称差集(包含在ss2中,但不同时在两个集合中的元素),返回新集合,不修改原集合 print(s.symmetric_difference(s2))``print(s ^ s2) {1, 2, 3, 6, 7, 8}(两种语法结果一致)
集合间关系判断相关 issubset() / <=(子集判断) s.issubset(s2) / s <= s2 判断s是否是s2的子集(s的所有元素都在s2中),返回布尔值True/False s3 = {4,5}``print(s3.issubset(s))``print(s3 <= s) True(两种语法结果一致)
issuperset() / >=(超集判断) s.issuperset(s2) / s >= s2 判断s是否是s2的超集(s2的所有元素都在s中),返回布尔值True/False print(s.issuperset(s3))``print(s >= s3) True(两种语法结果一致)
isdisjoint()(不相交判断) s.isdisjoint(s2) 判断两个集合是否没有公共元素,返回布尔值True/False s4 = {9,10}``print(s.isdisjoint(s4))``print(s.isdisjoint(s2)) True / False
集合辅助操作相关 转换为列表 / 元组 list(s) / tuple(s) 将集合转换为列表 / 元组(元素无序,因集合本身无序) print(list(s))``print(tuple(s)) [1, 2, 3, 4, 5](顺序随机) / (1, 2, 3, 4, 5)(顺序随机)
批量去重(列表转集合) list(set(列表))

6.字典

Python 字典是无序(Python 3.7 + 默认有序)、键值对映射、可变的容器类型,核心特性是 “通过键快速查找值”(哈希表实现),操作以 “键值对管理、查询匹配、结构调整” 为主。

格式: 字典名 = {键:值,键:值…} 已键值对的形式存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
dict_one = {"小陈": 1001,"小李":1002}
print(dict_one,type(dict_one))

#字典的Key(键)一般是字符串或数字,Value(默认值)可以是数字、字符串、列表、元组等
dict_two = {
"money":[100,200,300],#列表
"数字":(10,20,30,40),#元组
"no":{"apple","pear"},#集合
"steam":"游戏",#字符串
"小陈": { #字典
"性别":"男",
"age": 20,
"地址":"江西"
}
}


#遍历字典
dict_b = {"one":1,"two":2,"three":3}
for i in dict_b:
print(i,dict_b[i])

#方法2 字典名.item():
for k,v in dict_b.items():
print(k,v)


#空字典
dict_k = {}
dict_k1 = dict()
print(type(dict_k),type(dict_k1))

常用方法:

键值对查询与获取相关 键索引取值 d[键] 通过键获取对应的值,键不存在则抛出KeyError print(d["name"])``print(d["age"]) 小美 / 18
get() d.get(键, 默认值=None) 通过键获取对应的值,键不存在则返回默认值(默认None,不报错) print(d.get("score"))``print(d.get("gender", "未知")) 95 / 未知
keys() d.keys() 获取字典中所有的键,返回可迭代的dict_keys对象(可转为列表) print(d.keys())``print(list(d.keys())) dict_keys(['name', 'age', 'score']) / ['name', 'age', 'score']
values() d.values() 获取字典中所有的值,返回可迭代的dict_values对象(可转为列表) print(d.values())``print(list(d.values())) dict_values(['小美', 18, 95]) / ['小美', 18, 95]
items() d.items() 获取字典中所有的键值对(每个元素为(键, 值)元组),返回可迭代的dict_items对象 print(d.items())``print(list(d.items())) dict_items([('name', '小美'), ('age', 18), ('score', 95)]) / [('name', '小美'), ('age', 18), ('score', 95)]
setdefault() d.setdefault(键, 默认值=None) 获取键对应的值,键不存在则添加该键并赋值为默认值,返回对应的值 print(d.setdefault("age"))``print(d.setdefault("gender", "女"))``print(d) 18 / / {'name': '小美', 'age': 18, 'score': 95, 'gender': '女'}
键值对添加与更新相关 键索引赋值 d[键] = 值 键存在则更新对应的值,键不存在则添加新的键值对,直接修改原字典 d["score"] = 98``d["gender"] = "女"``print(d) {'name': '小美', 'age': 18, 'score': 98, 'gender': '女'}
update() d.update(字典/可迭代对象/关键字参数) 批量更新 / 添加键值对,键存在则更新,不存在则添加,直接修改原字典 d.update({"age": 19, "city": "北京"})``d.update(score=100)``print(d) {'name': '小美', 'age': 19, 'score': 100, 'gender': '女', 'city': '北京'}
键值对移除相关 pop() d.pop(键, 默认值) 删除指定键对应的键值对,返回对应的值;键不存在时,指定默认值则返回默认值,否则抛出KeyError deleted = d.pop("score")``print(d, deleted) {'name': '小美', 'age': 18} 95
popitem() d.popitem() 删除并返回字典中最后一个插入的键值对(元组形式),空字典调用抛出KeyError(Python 3.7 + 有序) item = d.popitem()``print(d, item) {'name': '小美', 'age': 18} ('score', 95)
clear() d.clear() 清空字典中所有的键值对,直接修改原字典,使其变为空字典 d.clear()``print(d) {}
键的判断与字典统计相关 in(成员运算符) 键 in d 判断指定键是否存在于字典中,返回布尔值True/False(仅判断键,不判断值) print("name" in d)``print("gender" in d) True / False
not in(成员运算符) 键 not in d 判断指定键是否不存在于字典中,返回布尔值True/False print("gender" not in d)``print("name" not in d) True / False
len()(内置函数) len(d) 统计字典中键值对的总个数(长度),非字典专属但高频使用,返回正整数 length = len(d)``print(length) 3
字典复制与转换相关 copy() new_d = d.copy() 复制字典,返回一个与原字典内容相同的新字典(浅拷贝),不修改原字典 new_d = d.copy()``new_d["age"] = 19``print(d, new_d) {'name': '小美', 'age': 18, 'score': 95} {'name': '小美', 'age': 19, 'score': 95}
转换为键 / 值列表 list(d.keys()) / list(d.values()) 将字典的键 / 值转换为列表,便于后续遍历和处理 print(list(d.keys()))``print(list(d.values())) ['name', 'age', 'score'] / ['小美', 18, 95]
转换为键值对列表 list(d.items()) 将字典的键值对转换为包含元组的列表,便于批量处理 print(list(d.items())) [('name', '小美'), ('age', 18), ('score', 95)]
字典遍历辅助相关 遍历键(默认) for 键 in d: 直接遍历字典,默认遍历所有的键 for k in d:``print(k) 依次输出:nameagescore
遍历键值对 for 键, 值 in d.items(): 遍历字典的所有键值对,同时获取键和值(最常用) for k, v in d.items():``print(f"{k}: {v}") 依次输出:name: 小美age: 18score: 95

7.容器互相转换

list(x) 列表 x 为可迭代对象(元组、字符串、集合、字典等)
tuple(x) 元组 x 为可迭代对象
set(x) 集合 x 为可迭代对象(元素需为不可变类型),自动去重
str(x) 字符串 任意对象(容器转换后为其「字符串表示形式」,非元素拆分)

九、模块

1.模块导入方式

  • 直接导入整个模块:import 模块名,使用时需加「模块名.」前缀;

  • 导入模块并指定别名:import 模块名 as 别名,简化长模块名的调用;

  • 按需导入指定内容:from 模块名 import 变量/函数/类,可直接使用,无需前缀;

  • 导入模块所有内容:from 模块名 import *(不推荐),易引发命名冲突。

2.包

  • 本质是包含 __init__.py 文件的文件夹,用于管理多个相关模块;

  • 可实现模块分层,简化大型项目的代码结构;

  • __init__.py 可配置包的导出内容,方便外部导入。

十、注解

1.Python 的 类型注解(Type Hint) 是一种用于标注变量、函数 / 方法的参数和返回值预期类型的语法,核心价值是提升代码可读性、提供开发工具提示、实现文档化说明,并非强制类型检查(Python 运行时会忽略类型注解,不影响程序执行)。

2.函数\方法注解 形参 : 类型

1
def f1(name : str):		#标识参数类型为字符串

3.函数 / 方法返回值注解 函数() -> 返回值类型

1
2
3
def sum(num1,num2) -> int:		#标识返回值为int类型
return num1 + num2

4.变量注解 变量 : 类型

1
2
name : str = "你好"
age : int = 18

5.复杂类型注解

1
2
lists[int] = [1,2,3,4]		#参数为int类型
dicts[str,int] = {"one":1,"two":2}

6.多类型注解

1
money : int | str

十一、面向对象编程

1.类的定义

class 类名{

成员属性;

成员方法;

}

调用: 类名();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#定义一个猫类,age,name,color 是属性,又称成员变量
class Cat:
#成员变量
age = None
name = None
color = None

#成员方法
def info(self) { #一定要加 self 类似于this!!!
print("我是小城")
}

#创建对象
cat1 = Cat()
cat1.name = "小黑"
cat1.age = 17
cat1.color = "黑色"
print(f"名字:{cat1.name},年龄:{cat1.age},颜色:{cat1.color}")
cat2 = cat1

print(cat2.age)#17
print(id(cat1.name),id(cat2.name))#地址是一样的!!!!

cat2 = None
# print(cat2.age) 此时cat2 指向 None 就会失去所有值!!!!

2.静态方法

使用: @staticmethod标识 此时调用该方法只要: 类名.方法() 并且函数不需要写self!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class dog:

name = None
age = None

def notsta(self):
print("不是静态方法")

#静态方法
@staticmethod
def sta():
print("静态方法,不用self")

#调用
dy = dog()
dy.notsta()
dog.sta()

3.构造函数

当实现该类时自动调用该方法

1
2
3
4
5
6
7
8
9
10
11
class person:
name = None
age = None
def __init__(self,name,age): #使用: def __init__ (self) {}
print("自动执行",name,age)
self.name = name #赋值给成员变量
self.age = age #赋值给成员变量
# @classmethod

p1 = person("科比",23)#不用调用__init__会执行方法
print(p1.age)#打印23

4.三大特性

面向对象三大特性: 封装、继承、多态

1.封装

1
2
3
4
5
封装是将抽象出的数据(属性)和对数据的操作封装(方法)在一起,将数据保护在内部,可以被用户调用
好处:隐藏实现细节、可以对数据验证、可以保护数据隐私
前面所使用的类都是公开的,可以随时调用,封装将数据私有化
封装格式:类中的属性和方法以双下划线开头命名 如:__name = None def __nn():
提供公共方法调用: def get_变量名 (self) {} def set_变量名 (self) {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class cleak:
#公共属性
name = "小陈"
#私有属性
__age = 19
def __init__(self):
print(f"公共属性:{self.name},私有属性:{self.__age}")

#提供公共方法,对私有属性操作
def set_age(self,age):
self.__age = age
def get__age(self):
return self.__age


#私有方法
def __cc(self):
print("私有方法")

#提供公共方法,调用私有方法
def f1(self):
self.__cc()


dc = cleak()
print(cleak.name)
# print(cleak.__age) 无法调用

#提供公共方法,对私有属性操作和获取
#获取私有属性
print(dc.get__age())

#修改私有属性
dc.set_age(14)
print(dc.get__age())


#dc.__cc()#私有方法不可以调用,会报错: 'cleak' object has no attribute '__cc'

#可以通过公共方法,调用私有方法
dc.f1()#可以调用私有方法!!!!

2.继承

1
2
3
4
5
6
7
8
9
10
11
创建一个A类、B类、C类,A类有B、C类所有的特征;B、C类可以继承A类。A类可以称为父类(基类),B、C为子类(派生类)
1.继承语法:class 子类(父类):
2.父类私有属性和方法 子类无法直接访问,需要父类有公共方法_
3.一个子类可以继承多个父类:class 子类(父类1,父类2,父类3)
如果两个父类有相同的属性和方法,那以父类1为基准!!!!!!!!!!!
4.super():
(1)当父类有一个构造器和子类有一个构造器时,子类要继承父类构造器并新增内容,
需要使用supper()。格式: def __init__(self):(子类的构造方法)
super().__init__()
(2)当子类和父类出现同名的成员,可以通过父类名、supper()父类的成员
5.方法重写:重新写和父类一样的属性名或者方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#父类
class fu:
name = None
age = None
sex = None
__score = None
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def get_score(self,score):
self.__score = score
def showmy(self):
print(f"姓名:{self.name},年龄:{self.age},性别:{self.sex},考试分:{self.__score}")


#子类
class stu(fu):
def test(self):
print("小学生考试")
#子类2
class pupli(fu):
def test(self):
print("大学生考试")

#调用子类1
stt = stu("小明",10,"男")
stt.get_score(99)
stt.showmy()

#调用子类2
pul = pupli("小陈",19,"男")
pul.get_score(129)
pul.showmy()


#super()方法
class A:
name = "小李"
age = 12
def test(self):
print("这是父类的方法")

class B(A):
name = "小陈"
age = 14
def test(self):
print("这是子类的方法")

def say(self):
A.test(self) #调用A类test
def hi(self):
super().test()#使用super调用A类test

tt = B()
tt.test()#这是子类的方法
tt.say()
tt.hi()

3.多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Animal:
def cry(self):
print("动物")

class Cat(Animal):
def cry(self):
print("小喵叫~~~~")

class Dog(Animal):
def cry(self):
print("小狗叫~~~~")


class Pig(Animal):
def cry(self):
print("小猪叫~~~~")

class diao:
def func(self,animal:Animal):
print(type(animal))
animal.cry() #使用函数调用上面的动物类

def f1(obj):
print(type(obj))
obj.cry()

cat = Cat()
dog = Dog()
pig = Pig()
Diao = diao()

Diao.func(cat) #调用动物类 cat
f1(pig)

5.魔法方法

1
2
3
4
5
6
7
8
9
10
11
12
什么是模式方法?在python中所有以双下划线包裹的都称为魔术方法,它是一个特殊的方法,不需要调用就会自己执行!
格式以 __xxx__(): 定义

系统自带:
1.__init__(self):初始化对象
2.__str__(self):定义对象转字符行为
3.__eq__(self,other):定义等于号的行为 x == y
4.__lt__(self,other):定义小于号的行为 x < y
5.__le__(self,other):定义小于等于号的行为 x <= y
6.__ne__(self,other):定义不等号的行为 x != y
7.__gt__(self,other):定义大于号的行为 x > y
8.__ge__(self,other):定义大于等于号的行为 x >= y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class A:
name = None
age = None

def __init__(self,name,age):
self.age = age
self.name = name

def __str__(self):
return f"{self.name} {self.age}" #此时不会输出类型和地址,而是数据 "小陈"和12!!!

def __eq__(self,other):
return self.name == other.name and \
self.age == other.age #此时为 True!!!!!!

def __le__(self,other):
if isinstance(other,A):
return self.age < other.age
else:
return "类型不一致不能比较"

a = A("小陈",12)
print(a)#默认输出类型+地址(10进制) <__main__.A object at 0x000001CD116C6900>
#我要输出"小陈"和12 __str__


b = A("小陈",12)

print("b == a:",b == a)#false 因为比较的是内存地址!!!!
#但想比较他们的内容 __eq__

# print("b < a:",a < b)
print(b != a)#false

十二、抽象类

1.Python 中的抽象类是包含一个或多个抽象方法的特殊类,抽象方法仅定义方法签名(无具体实现逻辑),要求其子类必须重写实现该抽象方法;抽象类无法直接实例化,仅作为子类的 “模板” 存在,用于规范子类的接口和行为。

python使用抽象类需要引包 ABC from abc import ABC,abstractmethod

抽象类需要继承ABC 方法使用@abstractmethod声明抽象方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from abc import ABC, abstractmethod

# 1. 定义抽象类(继承ABC,包含抽象方法)
class Animal(ABC):
# 普通方法(子类可复用)
def __init__(self, name):
self.name = name

# 抽象方法(仅定义签名,无实现,子类必须重写)
@abstractmethod
def cry(self):
pass

# 2. 定义子类,继承抽象类并实现抽象方法
class Dog(Animal):
def cry(self):
return f"{self.name}:汪汪汪"

class Cat(Animal):
def cry(self):
return f"{self.name}:喵喵喵"

# 3. 正常使用子类(可实例化,调用重写后的方法)
dog = Dog("大黄")
cat = Cat("小白")
print(dog.cry()) # 输出:大黄:汪汪汪
print(cat.cry()) # 输出:小白:喵喵喵

十三、异常

1.异常基本写法

1
2
3
4
5
6
7
1.语法:(try-except)
try:
可能会出现异常的代码
except 异常名 as 别名: except可以有多个
对异常内容处理
finally:
不管有没有异常,都会执行

2.异常类

异常类名称 异常描述 常见触发场景
SyntaxError 语法错误(编译时异常) 缺少冒号、括号不匹配、关键字拼写错误(如pront代替print
NameError 访问未定义的变量 / 函数 / 类 变量名拼写错误、使用未声明的变量(如print(a),其中a未定义)
ZeroDivisionError 除零错误 数字除以 0(如10 / 020 // 0
TypeError 类型错误(操作 / 函数应用于不兼容的类型) 不同类型直接运算(如10 + "20")、函数传入参数类型不符(如len(123)
ValueError 值错误(类型正确但值不合法) 字符串转数字失败(如int("abc"))、列表中查找不存在的值([1,2].index(3)
KeyError 字典键不存在 访问字典中未定义的键(如{"name":"Python"}["age"]
IndexError 索引越界错误 访问列表 / 元组 / 字符串的无效索引(如[1,2,3][5]"abc"[10]
FileNotFoundError 文件 / 目录不存在 以读模式打开不存在的文件(如open("nonexist.txt", "r")
AttributeError 属性 / 方法不存在 访问对象未定义的属性 / 方法(如"abc".append(1)class A: pass; A().b
ImportError/ModuleNotFoundError 模块导入失败 导入不存在的模块(如import nonexist_module)、从模块导入不存在的对象(from os import nonexist_func
KeyboardInterrupt 用户中断程序(Ctrl+C) 程序运行时按下Ctrl+C终止执行
Exception 所有非系统退出类异常的基类(可捕获大部分运行时异常) 作为异常捕获的兜底(不推荐直接捕获,优先捕获具体异常)

3.主动抛出异常

raise 关键字

1
2
3
4
5
6
try:
num3 = 10
num4 = 0
raise Exception("主动抛出异常")
except Exception as e:
print(f"出现{e}!!")

4.自定义异常

当 Python 内置异常无法满足业务需求时,可以自定义异常类,通常继承自Exception(不推荐继承BaseException,后者包含系统退出类异常)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class AgeError(Exception):		#自定义异常类
pass


while True:
try:
age = int(input("请输入年龄:"))
if not(18 <= age <= 120):
raise AgeError("年龄要在18——120之间")
break
except ValueError as e:
print("你输入的不是整数")
except AgeError as e:
print(e)

十四、文件操作

1.核心操作

模式 中文说明 操作权限 注意事项
'r' 只读(默认) 仅能读取文件内容,不能修改 / 写入 文件必须存在,否则抛出FileNotFoundError
'w' 只写 清空文件原有内容并写入新内容;若文件不存在,则创建新文件 会覆盖原有文件内容,慎用(需备份原有数据)
'a' 追加写 在文件末尾追加写入新内容;若文件不存在,则创建新文件 不会覆盖原有内容,适合日志记录、数据追加等场景
'r+' 读写 既能读取文件内容,也能写入 / 修改文件内容 文件必须存在,写入会覆盖光标位置后的内容
'w+' 读写 先清空文件(无文件则创建),再支持读写操作 会覆盖原有文件内容,读写一体场景使用
'a+' 追加读写 先追加写入(无文件则创建),也支持读取文件内容 读取时需先移动文件光标(默认光标在文件末尾),否则读取不到内容
'b' 二进制模式 配合上述模式使用(如'rb''wb'),用于操作二进制文件(图片、视频、压缩包) 无需指定encoding参数,操作的是字节流(bytes类型),而非字符串

注:需要引入 import os 包

2.读取文件

格式: open(文件路径,模式,编码类型) 不写编码类型默认utf-8

读取方法 功能描述 适用场景
file.read(size=-1) 读取文件内容,size指定读取字节数(默认-1,读取全部内容) 小文件读取(一次性加载到内存)
file.readline() 读取文件一行内容,返回字符串(包含行尾的\n 大文件逐行读取(节省内存)
file.readlines() 读取文件所有行,返回列表(每行内容为列表一个元素,包含\n 需按行处理文件,且文件不大 f = open(“test.txt”, ‘r’, encoding=’utf-8’) # 读取全部内容 content = f.read() print(“文件全部内容:”) print(content)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 f = open("test.txt", 'r', encoding='utf-8')
# 读取全部内容
content = f.read()
print("文件全部内容:")
print(content)
f.close() #关闭文件


f = open("large_file.txt", 'r', encoding='utf-8')
print("文件逐行内容:")
# 循环逐行读取,直到读取完毕(返回空字符串)
while True:
line = f.readline()
if not line:
break
f.close()


f = open("test.txt", 'r', encoding='utf-8')
lines = f.readlines()
print("文件行列表:", lines)
# 遍历处理每一行
for idx, line in lines:
print(f"第{idx}行:{line.strip()}")

3.写入数据

格式: open(文件路径,模式,编码类型) 不写编码类型默认utf-8

写入方法 功能描述
file.write(str) 将指定字符串写入文件,返回写入的字符数
file.writelines(list) 将字符串列表写入文件(不会自动添加换行符,需手动在列表元素中添加\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 覆盖写入(mode='w')
try:
f = open("write_test.txt", 'w', encoding='utf-8')
# 写入字符串(\n 用于换行)
f.write("Python 文件操作\n")
f.write("这是覆盖写入的内容\n")
print("覆盖写入完成")
finally:
f.close()

# 2. 追加写入(mode='a')
try:
f = open("write_test.txt", 'a', encoding='utf-8')
f.write("这是追加的内容,不会覆盖原有内容\n")
print("追加写入完成")
finally:
f.close()

4.新版文件读写

格式: with open(文件路径,模式,编码类型) as f: 此时会自动关闭文件,无需手动close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. 读取文件(自动关闭)
print("=== 自动读取文件 ===")
with open("test.txt", 'r', encoding='utf-8') as f:
content = f.read()
print(content)

# 2. 写入文件(自动关闭)
print("=== 自动写入文件 ===")
with open("with_write.txt", 'w', encoding='utf-8') as f:
f.write("使用with...as上下文管理器\n")
f.write("无需手动关闭文件,更安全高效\n")

# 3. 追加+读取(mode='a+',需移动光标)
print("=== 追加+读取文件 ===")
with open("a_plus_test.txt", 'a+', encoding='utf-8') as f:
# 先追加写入
f.write("追加的内容\n")
# 移动文件光标到文件开头(否则读取不到内容)
f.seek(0)
# 读取文件全部内容
content = f.read()
print("文件内容:", content)

5.文件操作

操作功能 传统模块(os) 现代模块(pathlib,推荐) 适用场景 关键注意事项
删除单个文件 os.remove(file_path) Path(file_path).unlink() 删除已存在的普通文件 1. 无法删除目录,否则抛IsADirectoryError;2. pathlib支持missing_ok=True(Python3.8+),忽略文件不存在的错误;3. 操作不可逆,无回收站。
重命名文件 os.rename(old_path, new_path) Path(old_path).rename(new_path) 修改文件名称 / 移动文件路径 1. 原文件必须存在,否则抛FileNotFoundError;2. 新路径若已存在,会覆盖(部分系统抛异常)。

6.目录操作

操作功能 传统模块(os/shutil) 现代模块(pathlib,推荐) 适用场景 关键注意事项
创建单个空目录 os.mkdir(dir_path) Path(dir_path).mkdir() 仅创建一级目录(父目录需已存在) 1. 目录已存在则抛FileExistsError;2. pathlib支持exist_ok=True,忽略目录已存在的错误。
递归创建多级目录 os.makedirs(dir_path) Path(dir_path).mkdir(parents=True) 创建多层嵌套目录(父目录可不存在) 1. 自动创建所有缺失的父目录;2. pathlib可搭配exist_ok=True,避免目录已存在报错。
删除单个空目录 os.rmdir(dir_path) Path(dir_path).rmdir() 删除无文件 / 子目录的空目录 1. 目录非空则抛OSError;2. 目录不存在则抛FileNotFoundError
递归删除非空目录(含所有文件 / 子目录) shutil.rmtree(dir_path) shutil.rmtree(Path(dir_path)) 删除包含文件、子目录的复杂目录 1. 依赖shutil模块,pathlib无原生递归删除方法;2. 操作不可逆,会彻底删除所有内容,慎用;3. 支持ignore_errors=True,忽略删除过程中的部分错误。
重命名目录 os.rename(old_dir, new_dir) Path(old_dir).rename(new_dir) 修改目录名称 / 移动目录路径 1. 原目录必须存在,否则抛FileNotFoundError;2. 新目录若已存在,部分系统会抛异常。

7.其他操作

操作功能 传统模块(os) 现代模块(pathlib,推荐) 功能说明
判断路径是否存在 os.path.exists(path) Path(path).exists() 校验文件 / 目录是否存在,返回布尔值
判断路径是否为文件 os.path.isfile(file_path) Path(file_path).is_file() 校验路径是否为有效文件,返回布尔值
判断路径是否为目录 os.path.isdir(dir_path) Path(dir_path).is_dir() 校验路径是否为有效目录,返回布尔值
获取当前工作目录 os.getcwd() Path.cwd() 返回当前程序运行的工作目录路径

十五、闭包

1.闭包是 Python 中基于函数一等对象特性作用域嵌套实现的一种特殊结构,指内部函数引用了外部函数(非全局)的变量 / 参数,且外部函数返回了这个内部函数。此时内部函数及其所引用的外部变量(称为「自由变量」)共同构成了闭包。用于延长外部函数变量周期

2.基本闭包

构成条件 具体说明
1. 嵌套结构 存在嵌套函数(外部函数内部定义了一个内部函数)
2. 变量引用 内部函数引用了外部函数的变量或参数(非全局变量,即自由变量)
3. 返回内部函数 外部函数的返回值是内部函数本身(不调用内部函数,仅返回函数对象)
1
2
3
4
5
6
7
8
9
10
def fn_outer():
num = 100
def fn_inner():
print(f"{num}")
return fn_inner #这里不能加上()


fn_inner = fn_outer()
fn_inner() #任然可以调用

3.数据持久化闭包

需要使用 nonlocal关键字 此时里面的函数可以修改外面的变量!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def create_accumulator(init_value=0):
# 自由变量:累加器初始值,被内部函数修改和引用
total = init_value

def accumulator(num):
# 注意:修改自由变量需用nonlocal声明(否则会被视为内部函数局部变量)
nonlocal total
total += num
return total

return accumulator

acc1 = create_accumulator()
print(acc1(5)) # 输出:5(0+5)
print(acc1(10)) # 输出:15(5+10)
print(acc1(3)) # 输出:18(15+3)

十六、装饰器

1.装饰器是一个可调用对象(通常是函数),它接收一个函数 / 类作为参数,返回一个增强后的新函数 / 类(或原函数的包装函数)。核心价值是「解耦」,将日志记录、性能统计、权限校验等通用功能与业务逻辑分离,通用功能的抽离,如日志打印、性能计时、权限校验、缓存处理、异常捕获等. 写法就是闭包

2.传统写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import time

#写一个装饰器,在调用评论和充值之前要先登录
def check_login(fn_name): #传递函数的地址
def fn_inner():
#这里进行处理
print("效验登录...")
time.sleep(2)
print("登录成功")
fn_name() #调用函数
return fn_inner

#发表评论
def comment():
print("你好")

#充值
def pay():
print("充值中...")


fn_inner = check_login(comment) #需要传递
fn_inner()

3.语法糖写法

使用@符号 @装饰器名 不要带()!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time

#写一个装饰器,在调用评论和充值之前要先登录
def check_login(fn_name): #传递函数的地址
def fn_inner():
#这里进行处理
print("效验登录...")
time.sleep(2)
print("登录成功")
fn_name() #调用函数
return fn_inner


#充值
@check_login #使用@符号,此时这个装饰器不要带()!!!!!
def pay():
print("充值中...")

pay() #调用即可


4.修饰器类型

(1).无参无返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time
def JiSuan(fn_name):
def fn_inner():

print("正在努力计算中...")
time.sleep(2)
fn_name()
return fn_inner


@JiSuan
def sum_two():
sum1 = 12
sum2 = 12
print(sum1 + sum2)


sum_two()

(2).有参无返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import time
def JiSuan(fn_name):
def fn_inner(a,b):
print("正在努力计算中...")
time.sleep(2)
fn_name(a,b)
return fn_inner


@JiSuan
def sum_two(a,b):
print(a + b)


sum_two(12,13)

(3)有参有返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import time
def JiSuan(fn_name):
def fn_inner(a,b):
print("正在努力计算中...")
time.sleep(2)
return fn_name(a,b)
return fn_inner


@JiSuan
def sum_two(a,b):
return a + b


sum_two(12,13)

5.多装饰器调用

多装饰器调用先调用近的后调用远的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#登录验证器
def login(fn_name):
def inner():
print("登录验证中...")
fn_name()
return inner

#验证登录器
def check_login(fn_name):
def inner():
print("验证用户名...")
fn_name()
return inner


@login #后调用这个,先打印这个
@check_login #先调用这个,后打印这个
def comment():
print("评论")

comment()

6.带参数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from functools import wraps
import time

# 带参数装饰器:接收日志级别参数
def log_decorator(level="INFO"):
# 中间层:接收被装饰函数
def decorator(func):
def wrapper(*args, **kwargs):
# 1. 增强逻辑:使用装饰器参数打印日志
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(f"[{current_time}] [{level}] 函数 {func.__name__} 开始执行...")
# 2. 调用原函数,接收返回值
func_result = func(*args, **kwargs)
# 3. 后续增强逻辑
print(f"[{current_time}] [{level}] 函数 {func.__name__} 执行完毕!")
# 4. 返回原函数返回值
return func_result
return wrapper
return decorator


# 用法1:使用默认日志级别(INFO),必须加括号
@log_decorator()
def add(a, b):
"""计算两个数的和"""
time.sleep(0.5) # 模拟函数执行耗时
return a + b


# 用法2:指定自定义日志级别(DEBUG)
@log_decorator(level="DEBUG")
def multiply(a, b):
"""计算两个数的积"""
time.sleep(0.3)
return a * b


# 用法3:指定错误级别日志(ERROR)
@log_decorator(level="ERROR")
def divide(a, b):
"""计算两个数的商"""
if b == 0:
raise ZeroDivisionError("除数不能为0")
return a / b


# 调用被装饰函数,验证效果
print("求和结果:", add(3, 5), "\n")
print("乘积结果:", multiply(4, 6), "\n")

try:
print("除法结果:", divide(10, 0))
except ZeroDivisionError as e:
print(e)