视频传送门:https://www.bilibili.com/video/BV1wD4y1o7AS 记得三连
print的规则
print可以输出的函数,数字,字符串,含有运算符的表达式,将数据输出到文件中。不进行换行输出(用逗号分开不需要换行的内容)
\t表示把print中的内容每四个字节一个\t单位,直到\t
如:print(‘hello/twolrd’) 则输出hello world 空格位有三个空格
print(‘helloooo/twolrd’) 则输出helloooo world 空格位有四个空格
\r表示回车,把后面的内容替换到前面
\b表示退一格
#原字符 不希望字符串中的转义字符起作用,就是使用原字符,就是在字符前面加上r,或者R
如print(r’hello\nworld’) 输出结果为hello\nworld
ASCLL表
Python中的保留字和标识符
保留字不能给对象命名
[‘False’, ‘None’, ‘True’, ‘and’, ‘as’, ‘assert’, ‘break’, ‘class’, ‘continue’, ‘def’, ‘del’, ‘elif’, ‘else’, ‘except’, ‘finally’, ‘for’, ‘from’, ‘global’, ‘if’, ‘import’, ‘in’, ‘is’, ‘lambda’, ‘nonlocal’, ‘not’, ‘or’, ‘pass’, ‘raise’, ‘return’, ‘try’, ‘while’, ‘with’, ‘yield’]
变量,函数,类和其他对象的起的名字就叫标识符
规则:
字母数字下划线_
不能以数字开头
不能是保留字
严格区分大小写
数字类型
数据类型:整数类型int、浮点型float、布尔类型boot、字符串类型 str
输出整数默认是十进制,要转换二进制前要加0b
print(‘十进制’,180)
print(‘二进制’,0b10101010)
输出结果为十进制 180
二进制 170
n1=1.1
n2=2.2
from decimal import Decimal
print(Decimal('1.1')+Decimal('2.2'))
#输出结果为3.3
如果没有加上decimal模块,则出现3.3000000000000003,浮点数底层问题,看情况是否要加模块
字符串分行打印使用三个单引号或三个双引号
类型转换
其他类型转换为int
a=5.88
b=True
c='hello'
d='90.2'
print(type(a),type(b),type(c),type(d))
print(int(a),type(int(a))) #float转换int,取整
print(int(b),type(int(b))) #boot转换int
print(int(c),type(int(c))) #转换失败,将str转换int类型时,字符串必须为数字串(整数),非数字串是不允许转换
print(int(d),type(int(d))) #转换失败,报错,字符串为小数串
其他类型转换为float
b='76'
c='hello world'
d=ture
print(float(b),type(float(b)))
print(float(c),type(float(c))) 错误,字符串中的数据如果是非数字串,则不允许转换
print(float(d),type(float(d)))
结果以下
76.0 <class 'float'>
1.0 <class 'float'>
Python中的注释
三种注释类型:
单行注释:#
多行注释:一对三引号
中文编码声明注释:在文件开头加上中文声明注释,用以指定源码文件的编码格式
Python中的输入函数input()
input()函数的基本使用
a=input('请输入一个整数:')
#a=int(a)
b=input('请输入另一个整数:')
#b=int(b)
print(int(a)+int(b))
#print(a+b)
Python中的运算符
print(-9//5)
print(9//-5)
结果均为-2,结论一正一负向下取整
print(9%-4) #公式 余数=被除数-除数*商 9-(-4)*3
提示 商=被除数//除数
结果为-3
链式赋值
a=b=c=20 #
print(a,id(a))
print(b,id(b))
print(c,id(c))
结果
20 1655989056
20 1655989056
20 1655989056
ID名为标识,内存地址
20赋值给a,即a指向20的内存地址,a根据20的内存地址找到20的值
参数赋值
a=10
a+=20 #a=a+20
print(a) 结果为30
变换变量的值
a,b,c=10,20,30
print(a,b,c) 输出结果:10,20,30
a,b=b,a
print(a,b,c) 输出结果:20,10,30
比较运算符(>,<,==,!=)
a=[11,22,33,44]
b=[11,22,33,44]
print('a等于b吗',a==b)
print(id(a))
print(id(b))
print(a is b)
print(a is not b)
结果
a等于b吗 True
1543453552968
1543453553672
False
True
and:全ture为true
or:有true为true
not:对bool类型操作数进行取反
如:a=ture
print(not a) 输出结果为false
in与not in:对字符串中是否存在指定字符进行判断
位运算符
#00010000
#00000110
#进行按位与运算,同1为1,得到00000000
print(16&6)
结果为0
#进行按位或运算,有1为1,得到00010110
print(16|6)
结果为22
#左移位运算符<<,<<后面的二进制值向左移动一位,相当于乘于2,高位溢出,低位补零
print(16<<2)
00010000
0001000000
结果为64
#右移位运算符>>,>>后面的二进制值向右移动一位,相当于乘于2,高位补零,低位截断
print(16>>2)
00010000
00000100
结果为4
运算符的优先级
程序的组织结构
顺序结构,选择结构,循环结构
顺序结构:程序从上到下顺序地执行代码,中间没有任何的判断和跳转,直到程序结束
对象的布尔值
选择结构
多分支结构
嵌套if
条件表达式
if……else 条件表达式
pass语句
answer=input('你是会员吗?y/n:')
if anwser='y':
pass
else:
pass
r=range(1,10)
print(list(r))
输出结果:1,2,3,4,5,6,7,8,9(从一开始到九的数)
--------------------------------
r=range(1,10,2)
print(list(r)
输出结果:1,3,5,7,9
print(r in 3)
输出结果:true
print(r not in 5)
输出结果:false
循环结构
# 定义初始化变量
# 用于储存偶数和
sum=0
a=1
# 条件执行体
# 条件判断
while a<=100:
# 条件判断是否为偶数
if a%2==0:
sum+=a
# 改变变量
a+=1
print('1到100之间的偶数和为:',sum)
注意缩进问题:比如if和a是while循环体里的,要进行缩进,a不在if体里的不用缩进
for-in循环
for item in 'python': #第一次取出的是P,将P赋值item,将item的值输出
print(item)
for i in range(10):
print(i)
输出结果为
0
1
2
3
4
5
6
7
8
9
for _ in range(5):
print('helloworld')
输出结果
helloworld
helloworld
helloworld
helloworld
helloworld
流程控制语句break
流程控制语句continue
嵌套循环
#打印九九乘法表
for i in range(1,10):
for j in range(1,i+1):
print(i,'*',j,'=',i*j,end='\t')
print()
#行数i=1,列数j=1
#行数i=2, 列数j=3,内循环循环两次
#行数i=3, 列数j=4,内循环循环三次,以此类推
'''
结果:
1 * 1 = 1
2 * 1 = 2 2 * 2 = 4
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16
5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25
6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36
7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49
8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64
9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
流程控制语句break与continue在二重循环中的使用
列表
变量可以存储一个元素,而列表可以存储N多个元素,程序可以对这些数据进行整体操作,列表相当于其他语言的数组。
列表示意图
列表的特点
创建与删除
查询操作
# 获取列表中指定元素
lst=['nihao','hello',98,99.9]
print(lst.index(98))
print(lst[1]) #中括号的数字表示索引的位置,正值从左到右,0开始表示左边第一个
#负值从有到左,从-1开始表示右边第一个
print(lst[-2])
#输出结果:
2
hello
98
# 获取列表中的多个元素
lst=['hello','world',78,60,20]
# start=1 stop=3 step=1,切片出来的列表是一个新的列表。
print(lst[1:3:1])
列表元素的增删改查
# 增加列表中的元素
lst=['nihao','hello',98,99.9]
print('添加元素之前',lst)
lst.append(100)
print('添加元素之后',lst)
# 结果
添加元素之前 ['nihao', 'hello', 98, 99.9]
添加元素之后 ['nihao', 'hello', 98, 99.9, 100]
# 向末尾一次性添加多个元素
lst2=['world',10,100]
lst.extend(lst2)
print('使用extend参数后',lst)
# 结果
使用extend参数后 ['nihao', 'hello', 98, 99.9, 100, 'world', 10, 100]
# 在任意位置上添加一个元素
lst.insert(1,66) # 在索引1的后面添加一个
print(lst)
# 结果
['nihao', 66, 'hello', 98, 99.9, 100, 'world', 10, 100]
#切片,在列表的任意位置添加至少一个元素,切掉的部分有一个新的列表置换
lst3=[123,456,789]
lst[1:]=lst3 # 将索引1及之后的元素替换成新的元素
print(lst)
#结果:
['nihao', 123, 456, 789]
# 列元素的删除操作
lst=[10,20,30,40,50,60,70]
print('原来列表中的元素',lst)
# 从列表中移除一个元素,若重复元素只移除一个
lst.remove(10)
print('进行remove操作后',lst)
# pop()根据索引移除元素,如果不指定索引,将删除列表中最后一个元素
lst.pop(-1)
print('进行pop操作后',lst)
# 切片操作:删除至少一个元素,将产生一个新的列表对象
new_lst=lst[1:3]
print('进行切片操作后',new_lst)
# 结果:
原来列表中的元素 [10, 20, 30, 40, 50, 60, 70]
进行remove操作后 [20, 30, 40, 50, 60, 70]
进行pop操作后 [20, 30, 40, 50, 60]
进行切片操作后 [30, 40]
-------------------------------------------------
# 不产生新的列表对象,而是删除原列表中的内容
lst=[1,2,3,4,5,6,7]
lst[1:3]=[]
print(lst)
# 结果
[1, 4, 5, 6, 7]
-------------------------------------------------
# 清楚列表中的所有元素
# del语句将列表对象删除
del lst
print(lst)
#结果
[]
NameError: name 'lst' is not defined
lst=[10,20,30,40,50,60]
lst[20]=100 #输出结果:[10,100,30,40,50,60]
lst[1:3]=[200,300,400] #输出结果:[10,200,300,400,40,50,60]
列表元素的排序
第一种方式(原列表发生改变,ID不变)
# 列元素的排序操作
lst=[4,7,3,8,2,9,1]
lst.sort()
print('排序后的列表:',lst) #结果:排序后的列表: [1, 2, 3, 4, 7, 8, 9]
# 通过指定关键字参数,将列表中的元素进行降序排序
lst.sort(reverse=True)
print(lst) #结果:[9, 8, 7, 4, 3, 2, 1]
lst.sort(reverse=False)
print(lst) #结果:[1, 2, 3, 4, 7, 8, 9]
第二种方式,原列表不发生改变,产生新的列表(id不同)
#使用内置函数sorted()对列表进行排序,将产生一个新的列表对象
lst=[13,10,45,90,60,70]
print('原列表',lst,id(lst))
#开始排序
new_lst=sorted(lst,reverse=False)
print('升序后的列表',new_lst,id(new_lst))
#指定关键参数,实现列表元素的降序排序
desc_lst=sorted(lst,reverse=True)
print('降序后的列表',desc_lst,id(desc_lst))
#结果
原列表 [13, 10, 45, 90, 60, 70] 2339603825096
升序后的列表 [10, 13, 45, 60, 70, 90] 2339603825800
降序后的列表 [90, 70, 60, 45, 13, 10] 2339603852232
列表推导式
lst=[i*i for i in range(1,6)]
print(lst)
#结果:[1, 4, 9, 16, 25]
字典
概念
Python内置的数据结构之一,与列表一样是一个可变数列
以键值对的方式存储数据,字典是一个无序的序列
原理
字典的实现原理与查字典类似,查字典是根据首部或者拼音查找汉字对应的页码,Python中的字典是根据key查找value所在的位置
字典的创建与删除
字典的创建
# 使用{}创建字典
scores={'张三':10,'李四':20,'王五':30}
print(scores,type(scores))
# 使用dict()创建字典
student=dict(name='jack',age=10)
print(student)
# 创建空字典
d={}
print(d)
字典元素的获取
scores={'张三':10,'李四':20,'王五':30}
print(scores['张三'])
# 如果输入不存在的键,print(scores['张三']),会出现报错
print(scores.get('张三'))
# 如果输入不存在的键,print(scores.get('张三')),不会出现报错,并返回None
# 字典元素的遍历
for i in scores:
print(i,scores[i],scores.get(i))
张三 10 10
李四 20 20
王五 30 30
scores={'张三':10,'李四':20,'王五':30}
print('张三' in scores)
print('张三' not in scores)
# 结果 ture false
del scores['张三'] #删除指定的key-value对
print(scores)
# 返回结果 {'李四': 20, '王五': 30}
scores.clear() #清空字典的元素
#返回结果 {}
字典的查询操作
scores={'张三':10,'李四':20,'王五':30}
# 获取所有的key
keys=scores.keys()
print(keys)
print(type(keys))
# 将所有的key组成的视图转成列表
print(list(keys))
# 获取所有的value
values=scores.values()
print(values)
print(type(values))
print(list(values))
# 获取所有的key-values对
items=scores.items()
print(items)
# ('张三', 10)称之为元组,转换之后的列表元素有元组组成的
print(list(items))
# 结果
dict_keys(['张三', '李四', '王五'])
<class 'dict_keys'>
['张三', '李四', '王五']
dict_values([10, 20, 30])
<class 'dict_values'>
[10, 20, 30]
dict_items([('张三', 10), ('李四', 20), ('王五', 30)])
[('张三', 10), ('李四', 20), ('王五', 30)]
---------------------------------------------
scores={'张三':10,'李四':20,'王五':30}
for key,value in scores.items():
print('key=%s,value=%s' %(key,value))
#结果
key=张三,value=10
key=李四,value=20
key=王五,value=30
---------------------------------------------
#使用枚举函数,同时拿到列表中的下表和元素
mylist=['a','b','c','d','e']
for num,list in enumerate(mylist):
print(num+1,list)
#结果
1 a
2 b
3 c
4 d
5 e
字典元素的增、删、改操作
字典元素的增与改
scores={'张三':10,'李四':20,'王五':30}
scores['陈六']=100
print(scores)
scores['陈六']=90
print(scores)
# 结果
{'张三': 10, '李四': 20, '王五': 30, '陈六': 100}
{'张三': 10, '李四': 20, '王五': 30, '陈六': 90}
字典的特点
字典生成式
可迭代的对象,指的是可以用for in循环进行遍历的对象
items=['fruit','food','other']
prices=['70','80','90']
d={ item.upper():price for item,price in zip(items,prices)}
print(d)
结果
{'FRUIT': '70', 'FOOD': '80', 'OTHER': '90'}
元组
什么是元组
元组的创建方式
t = ('hello', 'world', 98)
t2='hello','xiaoming',76 #省略小括号
t3=('world',)
t4 = tuple(('nihao','lilei',89))
# 结果
('hello', 'world', 98) <class 'tuple'>
('hello', 'xiaoming', 76) <class 'tuple'>
('world',) <class 'tuple'>
('nihao', 'lilei', 89) <class 'tuple'>
元组的遍历
# 元素的遍历
t = ('hello', 'world', 98)
print(t[0])
print(t[1])
print(t[2])
# 或者
for item in t:
print(item)
#元组的新增
tup1=(11,22,33)
tup2=('hello','python')
tup=tup1+tup2
print(tup)
#结果
(11, 22, 33, 'hello', 'python')
#元组的删除
del tup1
print(tup1) #报错,删除了整个元组,无法打印
集合
什么是集合
集合的创建
集合的增删改查操作
集合元素的新增操作
# 集合的创建
t1={10,20,30,40,50}
t1.add(60) #add一次添加一个元素
print(t1)
# t1.update({70,80,90})和t1.update((70,80,90))也可以新增元素
t1.update([70,80,90])
print(t1)
#结果
{40, 10, 50, 20, 60, 30}
{70, 40, 10, 80, 50, 20, 90, 60, 30}
集合元素的移除操作
t1.remove(10)
print(t1)
# t1.remove(100) 移除没有的元素,出现报错,而使用discard没有报错
t1.discard(20)
t1.discard(100)
print(t1)
集合间的关系
s1={10,20,30,40,50,60,70}
s2={10,20,30,}
s3={10,20,80}
s4={100,200,300}
print(s1.issubset(s2)) #s1是s2的子集吗?结果为false
print(s1.issubset(s3))
print(s2.issubset(s1)) #s2是s1的子集吗?结果为true
print(s1.issuperset(s2)) #s1是s2的超集吗?结果为true
print(s2.isdisjoint(s3)) #s2与s3没有交集吗?结果为false
print(s2.isdisjoint(s4)) #s2与s4没有交集吗?结果为true
集合生成式
总结
字符串
字符串的驻留机制
字符串的常用操作
s='hello,hello'
print(s.index('lo')) #3
print(s.rindex('lo')) #9
print(s.find('lo')) #3
print(s.rfind('lo')) #9
大小写转换不能对元组和列表进行转换
s2='hello,world'
print(s2.center(20,'*'))
#结果:****hello,world*****
对元组和列表报错
s='hello world python'
lst=s.split()
print(lst) #从左边开始劈分,默认是空格字符串,返回是一个列表 ['hello', 'world', 'python']
s1='hello|world|python'
print(s1.split(sep='|')) #从左边开始劈分,以|作为劈分依据,返回个列表 ['hello', 'world', 'python']
print(s1.split(sep='|',maxsplit=1)) #从左边开始劈分,以|作为劈分依据,最大劈分次数为1,
# 劈分后剩下的子串作为单独的一部分,返回个列表 ['hello', 'world|python']
print(s1.rsplit(sep='|'))
print(s1.rsplit(sep='|',maxsplit=1)) #结果:['hello|world', 'python']
注释:水平制表符为空格,\t
print('2.','李四abc'.isalpha())
print('3.','张三'.isidentifier())
print('4',' '.isspace())
print('5.','123adb'.isalnum())
print(s2.replace('world','java')) #字符串替换replace,将world替换成java
s3='hello,python,python,python'
print(s3.replace('python','java',2)) #字符串替换replace,将Python替换成java,替换两次
s4=['hello','world','python'] #字符串组合,组合的元素必须是元组或列表
print('|'.join(s4)) #结果:hello|world|python
print(''.join(s4)) #结果:helloworldpython
print('*'.join('python')) #结果:p*y*t*h*o*n
字符串的比较
print('python'>'pytho') #true
print(ord('c')>ord('a')) #true
print(ord('c'),ord('a')) #99 97
print(chr(98)) #b
字符串的切片操作
# 字符串切片操作
s1='hello,python'
print(s1[1:5:1]) #从1开始截取到5(不包括5),步长为1
结果:ello
print(s1[::2]) #从0开始截取到最后,步长为2
结果:hlopto
print(s1[::-1]) #从0开始截取到最后,步长为-1
结果:nohtyp,olleh
print(s1[-6::1]) #索引从-6开始,到字符串最后一个元素结束,步长为1
结果:python
格式化字符串
name='张三'
age=14
money=14.3
new_str='我叫{0},今年{1}岁,身上有{2}元'.format(name,age,money)
print(new_str)
print('我叫%s,今年%i岁,身上有%.2f元' % (name,age,money))
# 结果
我叫张三,今年14岁,身上有14.3元
我叫张三,今年14岁,身上有14.30元
#表示字符串的宽度
print('%d' % 99) #字符串没有宽度
print('%10d' % 99) #10表示宽度
print('%.4f' % 3.1415296) #.4表示小数点后三位
print('%10.3f' % 3.1415296) #宽度+小数点后三位
#结果
99
99
3.1415
3.142
字符串的编码转换
s='斗破苍穹'
print(s.encode(encoding='GBK')) #在GBK编码格式中,一个中文占两个字节
print(s.encode(encoding='UTF-8')) #在GBK编码格式中,一个中文占三个字节
byte=s.encode(encoding='GBK') #编码
print(byte.decode(encoding='GBK')) #解码
byte=s.encode(encoding='UTF-8') #编码
print(byte.decode(encoding='UTF-8')) #解码
#结果
b'\xb6\xb7\xc6\xc6\xb2\xd4\xf1\xb7'
b'\xe6\x96\x97\xe7\xa0\xb4\xe8\x8b\x8d\xe7\xa9\xb9'
斗破苍穹
斗破苍穹
函数
函数的创建和调用
def cale(a,b):
c=a*b
return c
print(cale(5,4)) #结果为20
函数的参数传递
#函数的定义
def fun(arg1,arg2):
print('arg1=',arg1)
print('arg2=',arg2)
arg1=100 #重新赋值为100
arg2.append(10) #追加100
print('arg1=', arg1)
print('arg2=', arg2)
print('-------------------------------')
#函数的调用
n1=11
n2=[22,33,44]
print(n1,n2) #结果:11 [22, 33, 44]
fun(n1,n2) #将位置传参,agr1,arg2是函数定义的形参,n1,n2是函数调用的实参,总结:形参和实参名称可以不一致
print(n1,n2) #结果:11 [22, 33, 44, 10]
print('===============理解函数创建===========================')
def acl(s1,s2): #创建acl函数,s1,s2为形参
s1=50 #函数体,将s1修改为50,s2追加90
s2.append(90)
#对acl函数的调用
s1=5
s2=[10,20,30,40]
acl(s1,s2) #调用
print(s1,s2) #调用后的结果
'''在函数的调用过程中,进行参数的传递
如果是不可变对象,在函数体的修改不会影响到实参的值 arg1的值修改为100,不会影响n1的值
如果是可变对象,在函数体的修改会影响到实参的值 arg2的修改,append(10),会影响到n2的值
'''
#结果
11 [22, 33, 44]
arg1= 11
arg2= [22, 33, 44]
arg1= 100
arg2= [22, 33, 44, 10]
-------------------------------
11 [22, 33, 44, 10]
===============理解函数创建===========================
5 [10, 20, 30, 40, 90]
函数的返回值
def fun(num):
odd=[] #存奇数
even=[] #存偶数
for i in num: #遍历形参的元素
if i%2:
odd.append(i) #余数为1,结果为奇数,为true,存到odd中
else:
even.append(i) #余数为0,结果为偶数,为false,存到even中
return odd,even
lst=[10,20,33,44,47,57,60]
print(fun(lst))
#结果
([33, 47, 57], [10, 20, 44, 60])
结论
1、如果函数没有返回值,【函数执行完毕后,不需要给调用出提供数据】return可以省略不写
2、函数的返回值如果是1个,直接返回类型
3、函数的返回值如果是多个,返回结果是元组
函数的参数定义
def fun1(a=30, b=20):
print(a, b)
fun1(100)
fun1(50, 60)
#结果
100 20
50 60
def fun1(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
fun1(10,20,30)
#将序列中的每个元素都转换为位置实参 使用*
lst1=[11,22,33]
fun1(*lst1)
fun1(a=100,b=200,c=300)
#将字典中的每个键值对都转换为关键字实参 使用**
dict={'a':111,'b':222,'c':333}
fun1(**dict)
#结果
a= 10
b= 20
c= 30
a= 11
b= 22
c= 33
a= 100
b= 200
c= 300
a= 111
b= 222
c= 333
def ext(a,b,*,c,d): #从*之后的参数,在函数调用时,只能采取关键字参数传递
print('a=', a)
print('b=', b)
print('c=', c)
print('d=', d)
# ext(10,20,30,40) #位置实参传递
# 要求,c,d只能采用关键字实参传递
ext(10,20,c=30,d=40) #前两个参数,采用的是位置实参传递,而c,d采用的是关键字实参传递
# 函数定义时的形参顺序问题
def ext1(a,b,*,c,d,**args):
pass
def ext2(*args,**args2):
pass
def ext3(a,b=10,*args,**args2):
pass
变量的定义域
递归函数
def fun(n):
if n==1:
return 1
else:
return n*fun(n-1)
print(fun(6))
#结果:
720
斐波那契数列
#要求将前两位的数字相加等于第三位,第一和第二数字为1
def fib(n):
if n==1:
return 1
elif n==2:
return 1
else:
return fib(n-1)+fib(n-2)
print(fib(6))
#结果:8
正在更新~~~~
作者:月光染衣袂
转发请加上该地址 : https://blog.csdn.net/weixin_46860149/article/details/118232264
如果笔记对您有用,请帮忙点个赞!