python基础语法
重点:变量、input输入、格式化输出print
1、注释
- 快捷键:ctrl + /
- 分类:
- 单行注释:#
- 多行注释:""" 或 '''
- 多行注释的快捷键:【shift + 点击3次(英文状态下的)"】
- 注释的代码不会被python解释器执行
2、变量
存储数据的容器、存储的数据是临时的,即在程序执行过程中可发生变化(E.G.覆盖、重新赋值等)
2.1、变量命名规则
- 由数字、字母、下划线组成
- 不能以数字开头
- 严格区分大小写
- 不能使用python中的关键字
- 通过help('keywords'),可查询python中所有的关键字
2.2、变量命名举例
- 大驼峰式:E.G. MyName
- 小驼峰式:E.G. myName
- 采用下划线:E.G.my_name
- 也可采用中文来定义变量名,即【姓名 = "张三"】。
- 但不推荐使用中文来命名变量
3、数据类型
3.1、七大数据类型
- 数值类型
- 整型:int
- 浮点型:float
- 字符串类型:string
- 通过 双引号" 或 单引号' 引起来的数据
- 多行字符串:使用 """ 或 '''
- 布尔类型:bool
- 取值为:True或False
- 列表类型:list
- 元组类型:tuple
- 字典类型:dict
- 集合类型:set
3.2、数据类型的判断
- type(变量名) # 查看某变量的数据类型
4、输出
- print(变量名1,变量名2,……,变量名n)
- print(f"我叫{name},今年{age}岁了") # 格式化输出
- print("姓名%s,蔬菜%f元一斤" % (name,price))
- print("姓名{},蔬菜{}元一斤".format(name,price))
- 保留2为小数:
- print(round(price,2))
- print("%.2f" % price)
5、输入
- input()函数:实现输入操作
- 举例
name = input("提示信息:")
- 举例
- 注意事项:通过input()输入的所有数据都是字符串类型
python运算符
1、数据类型的转换
1.1、进行数据类型转换的原因
- input()方法返回的所有结果都是字符串类型,但字符串不能进行数学运算。
- 字符串进行相乘或相加的结果:即为字符串的拼接或复制。
1.2、常见数据类型转换的方法
- int():将其他数据类型转换为整型
- float():将其他数据类型转换为浮点型
- str():将其他数据类型转换为字符串型
- 重点注意:
- python不能将包含小数点的字符串(例如:"12.23")直接转换为整型(例如:12),否则将抛出ValueError异常。
- 例如:int("12.23") # 报错
- 解决方案:int(float("12.23")) # str先转float、float在转int。
- 但对于不含小数点的字符串(例如:"12")可以直接转换为整型(例如:12)
- 例如:int("12") # 正常输出整型12
2、运算符
2.1、算术运算符
- +、-、*(乘)、/(除)、//(整除)、%(取余)、**(幂指数)
2.2、赋值运算符
- 赋值:=
2.3、复合赋值运算符
- +=、-=、*=、/=、//=、%=、**=
- 即a**=b 等价于 a = a**b 等价于 a = a^b
2.4、比较运算符
- ==、!=、>、<、>=、<=
- 返回的数据类型为:布尔类型(True 和 False)
2.5、逻辑运算符
- and、or、not
- not:取反
2.6、运算符的优先级
- 小括号():优先级最高
python选择判断结构
1、if选择判断结构
- (双分支结构)二选一:if-else
- (多分支结构)多选一:if-elif-elif....else
- if嵌套:if中继续嵌套if
2、三目运算符
- 本质:if-else结构的简化形式
- 例如:(求两个数中的最大值)
- max = 10 if 10 > 20 else 20 # max = 20
python中的循环
1、while循环
1.1、while循环语法(3步)
- ①初始化计数器
- ②编写循环体【即确定需要执行多少次循环】
- 重复执行的代码段
- ③更新计数器 # 使循环停止的关键点
1.2、示例(求1-100的和)
- i = 1 # 定义一个计数器
- result = 0
- while i <= 100: # 编写while循环体
- # 重复执行的代码
- result += 1
- i += 1 # 更新计数器
2、for循环
2.1、for循环的语法
- for 临时变量 in 容器:
- # 重复执行的代码段
2.2、for循环的主要作用
- 作用:for循环结构主要用于容器中数据的遍历。
- 容器:
- 字符串
- 列表
- 元组
- 字典
- 集合
- 其他可迭代对象等
- 补充:range()内置函数
- 函数range:生成一段连续的整数序列
- 格式:range(start,end,step)
- range函数产生的序列为:左闭右开
- 即产生的序列从start开始一直到end-1。【无法取到end值】
- range(1,100):产生1到99的整数序列
- 参数:
- start:从start开始(默认从0开始)
- stop:到stop技术(不包括stop)
- step:步长(默认为1)
- 步长为正:
- range(1, 5, 1) # 产生1,2,3,4
- 步长为负:
- 注意:若step<0,则必须要求start>stop
- range(5, 1, -1) # 产生5,4,3,2
- 步长为正:
3、for循环与while循环的区别
- 适用范围不同:
- for循环主要用于遍历可迭代对象、容器等。
- while循环主要适用于循环次数已知的情况。
- 循环终止条件不同:
- for循环在遍历完成后自动结束循环。
- while循环需满足某条件后(或手动终止)才能结束循环。
4、循环中的两大关键字
- 主要作用:用于退出循环。
- break:终止整个循环
- continue:跳出某一次循环,继续执行下一次循环
- 使用continue时,需注意手动更新计数器,否则可能使程序进入死循环
- break与continue的区别(例子):
- 5个苹果,在吃完3个后、吃饱了,则在i == 4时,break
- 5个苹果,在吃第3个时、苹果是坏的,则在 i == 3时,continue,同时计数器i自增,继续从第4个苹果开始吃。
python序列(容器)
- 序列:是指一组按顺序排列的值的集合,可以通过索引访问其中的元素。
- 特殊:集合和字典不支持索引、切片、相加、相乘操作。
- python中的序列类型:字符串、列表、元组、集合、字典。
- 注意:序列是python数据类型的一种。
- 补充:python中的(七大)数据类型:
- 数值型(int型、float型)、布尔型、字符串、列表、元组、集合、字典。
- 补充:python中的(七大)数据类型:
1、字符串切片
- 作用:截取某一部分的字符串
- 语法:[start:end:step]
- 由切片产生的序列为:左闭右开【同函数range()】
- 索引下标:
- 正索引:0,1,2,3,……
- 负索引:……,-3,-2,-1
- 步长(step):【step默认为1】
- 若step > 0:则为从前往后切片字符串(正索引)
- 若step < 0:则为从后往前切片字符串(负索引)
- 若step<0,则必须要求start>stop
- 例如:
- str1 = "abcdef"
- 正索引:print(str1[-4,-1,1]) # cde
- 负索引:print(str1[-1,-4,-1]) # fed
2、python中常见内置函数(方法)
容器(字符串、列表、元组、字典、集合)都可以用于遍历操作。
2.1、字符串的内置操作
- 查找:
- find()方法:返回查找某字符串中的首字母在整个字符串中的索引下标;若查找不到,则返回-1。
- 返回索引下标
- 替换:
- replace()方法:主要用于关键字替换、过滤功能等。
- 格式:replace(被替换字符,替换字符,替换次数)
- 返回替换后的新字符串。
- 切割:
- split()方法:按照指定字符切割字符串
- 返回列表
- 拼接:
- join()方法:按照指定字符进行字符串的拼接
- 返回字符串str
- 大小写转换:
- lower():大写->小写
- upper():小写->大写
- 返回字符串str
- 计数:
- count():统计某个字符串或字符在整个字符串中出现的次数
- 返回int型
2.2、列表的内置操作
- 增:
- append():在列表的末尾添加元素
- insert():插入元素到指定的位置
- insert(待插入元素的索引(下标),待插入的内容)
- 删:
- remove():删除列表中指定的元素
- 改:
- 列表名[索引] = 修改后的值
- 查:
- 单个元素的访问: 列表名[索引]
- len()方法:返回列表中元素的个数
- index()方法:返回指定元素的索引下标
- 排序:
- sort()方法:默认为升序排序
- sort(reverse=True):为降序排序
- 降序排列的原理:
- 先用sort方法进行升序排序(即从小到大),在通过reverse方法进行翻转。
- 降序排列的原理:
- 翻转:
- reverse()方法:将列表从后往前进行翻转。
2.3、元组的内置操作
- 元组一旦被创建,则它的元素就不可更改。(所以元组的操作方法较少)
- 查:
- 元组名[索引]
- len()方法:返回元组中元素的个数
2.4、字典的内置操作
- 增:
- 初始值的增加:字典名[key] = value
- 删:
- 删除单个键值对:del 字典名[key]
- 删除整个字典: del 字典名
- 改:
- 已有键值对的修改:字典名[key] = value
- 查:
- keys():查询字典中所有的键keys
- values():查询字典中所有的值value
- items():查询字典中所有的键值对key:value
- 遍历:
- 例如:遍历字典键、值
- for key, value in 字典名.items():
- print(key,value)
- for key, value in 字典名.items():
- 例如:遍历字典值
- for value in 字典名.values():
- print(value)
- for value in 字典名.values():
- 例如:遍历字典键
- for key in 字典名
- print(key)
- for key in 字典名.keys():
- print(key)
- for key in 字典名
- 例如:遍历字典键值对
- for key_val in 字典名.items()
- print(key_val)
- for key_val in 字典名.items()
- 例如:遍历字典键、值
2.5、集合的内置操作
- 集合特点:
- 无序:因此不能通过索引下标来访问集合中的元素
- 去重:集合中自动去除重复的元素
- 增:
- add()方法:向集合中添加元素
- 删:
- remove()方法:删除集合中指定的元素
- 因此:不能通过集合的索引下标对集合进行某些操作(例如:查、改)
3、容器类型之间的相互转换
- 列表、元组、集合三者之间可相互转换。【但字典不可以】
- list():将某数据类型转换为列表
- set():将某数据类型转换为集合
- tuple():将某数据类型转换为元组
4、拆包
- 作用:可用于对两个数据进行调换
- 例如:a1,a2 = a2,a1
- num1,num2 = (10,20)
- print(num1,num2) # 输出10 20
- 元组拆包操作
- 变量名1,变量名2,变量名3,…… = 元组名
- 列表拆包操作
- 变量名1,变量名2,变量名3,…… = 列表名
- 字典等拆包操作
5、列表推导式
- 作用:用于代码的简化
- 语法:
- 变量名 = [ 表达式 for 临时变量 in 容器 if 条件判断 ]
- 例如:
- list1 = [i for i in range(5)]
- print(list1) # [0,1,2,3,4]
- list2 = [i for i in range(5) if i%2 == 0]
- print(list2) # [0,2,4]
函数
1、函数的简要介绍
- 分类:
- 普通函数(有名函数)
- 普通函数的定义:
- def 函数名(参数1,参数2,……):
- # 函数体
- return 返回值 # 一个函数可以有返回值,也可没有
- def 函数名(参数1,参数2,……):
- 注意:一个函数内部至多只有1个return返回值(0个或1个)。
- 若有2个及以上的return返回值时,仅执行最前面的1个return。
- 一个return一次也可返回多个值,但返回的数据类型为元组。
- return 1,2,3,4 # 以(1,2,3,4)元组的类型返回值
- 普通函数的定义:
- 匿名函数(无名函数):lambda
- 匿名函数的定义:
- lambda 函数参数:函数返回值
- 例如:实现两数相加的函数
# 1、add_num()为函数。2、num1,num2为函数参数。3、num1+num2为函数的返回值
add_num = lambda num1,num2:num1+num2
print(add_num(3,17)) # 20
- 匿名函数的定义:
- 普通函数(有名函数)
- 函数的定义与调用
- 函数定义:同上
- 函数调用:
- 函数名(参数……)
- 注意:定义的函数不会被程序执行,仅在调用函数时才会被执行。
- 函数说明文档
- 实质:说明文档即注释
- 例如:
- def 函数名():
- """ 此处为此函数的说明文档 """
- pass # 仅起占位作用(使程序不会报错)
- def 函数名():
2、变量的作用域
- 实质:变量的作用域即变量的作用范围。
- 分类:
- 局部变量:定义在函数内部的变量
- (仅可在函数内部使用)
- 注意:局部变量不能在函数外部被使用或访问
- 全局变量:定义在函数外部的变量
- (在整个python文件中都可直接使用:即可在函数内部、也可在函数外部使用的变量)
- 局部变量:定义在函数内部的变量
- global关键字:
- 作用:在函数内部对全局变量进行修改
- 例如:
- glob_var = 1 # 全局变量glob_var
- print(glob_var) # 1
- def 函数名():
- global glob_var # 对全局变量glob_var使用global关键字
- glob_var = 100
- 函数名() # 调用上述函数
- print(glob_var) # 100 (即实现对全局变量的修改)
3、函数的参数
3.1、形参与实参
- 形参:函数定义时所用的参数(用于占位)
- 实参:函数调用时所用的参数(用于传值)
- 关系:
- 在函数调用过程中,实参给形参赋值。
3.2、参数的形式
- 位置参数
- 有顺序要求:实参传递的值必须与形参一 一对应
- 关键字参数
- 无顺序要求:实参传递的值不一定需要与形参一 一对应
- 注意:使用关键字实参时,必须准确地指出定义中的形参名。
- 调用函数时:
函数名(形参名1=实参值1,形参名2=实参值2,……)
- 无顺序要求:实参传递的值不一定需要与形参一 一对应
- 缺省参数(默认参数)
- 在函数定义时,预先为某形参赋初值。
- (在之后的函数调用中,若没有为此形参进行传值,则采用函数定义时设置的默认值),使程序不会报错。
- 注意:缺省参数必须只能放在所有形参的最后
- 定义函数时:
def 函数名(形参名1,形参名2,……,形参名n=初始值):
- 不定长参数(可变参数)
- 作用:在进行函数定义时,若不知道今后实参的数据类型或传值的个数,则形参可暂时采用不定长参数。
- 不定长元组参数:*args
- (实参向形参)传参的数据类型为:元组
- 函数定义时:
def 函数名(*args):
print(args) # 输出的数据类型为元组
- 调用函数时,接收来自非关键字参数的传值。
- 函数名(实参1,实参2,……)
- 不定长字典参数:**kwargs
- (实参向形参)传参的数据类型为:字典
- 函数定义时:
def 函数名(**kwargs):
print(kwargs) # 输出的数据类型为字典
- 调用函数时,接收来自关键字参数的传值。
- 函数名(参数名1=参数值1,参数名2=参数值2,…… )
面向对象编程(OOP)
- 注意:以下说法均是等价的。
- 实例化类 <==> 创建对象 <==> 实例化后的对象
1、面向对象与面向过程的区别
- 面向过程:【c语言】
- 注重解决问题详细且逐步的过程
- 面向对象:【python、java等】
- 注重调用解决问题所封装的主体中的属性和方法。
2、OPP中的概念
2.1、面向对象思想
- 面向对象是一种解决问题的思维方式。
- 不是简单的将功能进行封装(即函数)。
- 而是对调用该功能的主体进行封装(即将属于该主体的属性和功能统一封装)。
- 使用:先实例化类,在使用实例化后的对象来调用类中的属性、方法。
2.2、类
- 定义:
class 类名():
# 属性
# 方法(即函数)
- 目的:用来实例化类(即创建对象)
- 建议:将类名的首字母大写(大驼峰式命名),用以区分函数名。
- 实例化类:【即由类创建对象的过程】
- 对象名 = 类名()
- 一个类可以创建多个对象
- 类比于:人类有一千多亿的人民、而不是几个。
- self关键字:【self就是实例化后的对象本身】
- 每个类方法中都有一个self。
- 类中的self就是实例化后的对象,并指向该对象本身。
- 若有(多个实例化后的对象)调用同一个方法,则(多个实例化后的对象)之间对应的self值不同。
- 因为self就是(实例化后的)对象。不同(实例化后的)对象占用的存储空间自然是不同的。
- 在类方法中的内部:
- print(self) # 打印输出(实例化后的)对象在计算机中内存地址。
2.3、对象
- 定义:(对象即实例化类)
- 对象名 = 类名()
- 目的:使用对象来实现相应操作(即通过对象来调用类中的属性、方法)。
- 调用类属性:对象名.属性名
- 调用类方法:对象名.方法名()
- 组成:对象属性(特征)、对象方法(函数)。
- 对象属性:
- 在类的外部定义对象的属性:【对象名.属性名 = 属性值】
- 在类的外部获取对象属性:
- 在类的外部使用:print(对象名.属性名) 即可。
- 在类的内部获取对象属性:
- 在类的内部使用:print(self.属性名) 即可。
- 在类的外部获取对象属性:
- 在实例化类的同时,给对象的属性赋值::【构造函数 __init__()】
- 可使用魔术方法。
- 在类的外部定义对象的属性:【对象名.属性名 = 属性值】
2.4、类与对象的区别
- 是否占用计算机内存空间
- 类:是一个抽象概念,在定义时不会真正占用计算机的内存空间。
- 对象:实例化后的对象是一个具体事物、故占用内存空间。
- 类:定义对象的模板,包括类属性和类方法。
- (类是对象的一种规范,类本身基本上什么都做不了)
- 类属性:可被所有实例化后的对象所共享。直接在类属性中定义。
- 对象:类的实例化,具有特定的对象属性和对象方法。
3、魔术方法
- 在Python中,形如 __xxx__() 的函数叫做魔法方法,指的是具有特殊功能的函数。
- 调用时机:魔术方法一般不需要手动调用,在满足某个条件时自动调用。
-
常用的魔术方法:
-
构造函数:__init__()
- 作用:在实例化类的同时,给对象的属性赋值。
- 调用时机:在创建一个对象时默认被调用,不需要手动调用。
- __init__(self)中的self参数,不需要手动传递,python解释器会自动把当前的对象传递过去。
-
对象字符串方法:__str__()
- 作用:打印输出在这个方法中自定义return的数据。
- 引入原因:若不使用对象字符串方法__str__(),当执行print(对象名)时,打印输出为对象的内存地址。
- 调用时机:在类的外部打印对象时(即print(对象名)),自动被调用。
- 注意:在类的内部定义时,必须使用return返回一个字符串类型的数据。
-
删除函数(析构函数):__del__()
- 作用:删除对象、关闭文件、关闭数据库连接等
- del 对象名
- 调用时机:在类的外部使用(del 对象名)(或文件运行结束后),自动被调用。
- 作用:删除对象、关闭文件、关闭数据库连接等
-
python中面向对象的三大特性
- 面向对象的三大特性:
- 封装性
- 继承性
- 多态性
1、面向对象的封装
封装:将主体的属性和方法写入到类里的操作
1.1、封装中的私有属性和私有方法
- 设置目的:
- 有时不太希望,用户在类的外部直接对类内部中的某个属性和方法进行操作。【此时可将此属性或方法封装为私有属性、私有方法】
- 私有属性和私有方法的设置:
- 在class定义的类中:在属性名、方法名前面添加2个下划线(__)即可。
- 私有属性的访问:
- 私有属性不能在类的外部被直接访问。【E.G、对象名.__私有属性名 # 报错】
- 在类的外部对私有属性进行访问:
- 在类的内部,提供一个专门给外部获取私有属性的接口(即方法)
- 在类的外部,直接调用获取私有属性的方法即可。
- 私有属性的修改:
- 在类的外部对私有属性进行修改:
- 在类的内部,定义一个专门给外部修改私有属性的方法(即接口)
- 在类的外部,直接调用修改私有属性的方法即可。
- 在类的外部对私有属性进行修改:
- 私有方法的调用:
- 私有方法不能在类的外部被直接调用。【E.G、对象名.__私有方法名() # 报错】
- 在类的外部对私有方法进行调用:
- 在类的内部:定义一个专门给外部调用私有方法的函数(即接口)
- 在类的外部:直接使用调用私有方法的函数即可
- 注意:不能在类的外部对私有方法进行修改(只能对其进行调用(访问))。
2、面向对象的继承
- 继承:A类使用了另一个B类成员的属性和方法,即A类继承了B类。
- 注意:子类继承父类后,子类可以使用父类中所有的属性和方法。
- 分类:
- 单继承:一个类仅继承一个父类
- 特性:传递性(即多层继承)
- 例如:Teacher类继承了Person类,Student类继承了Teacher类;由于单继承的传递性,则Student类也继承了Person类的属性和方法。
- 特性:传递性(即多层继承)
- 多继承:一个类继承了多个父类
- 单继承:一个类仅继承一个父类
- 父类与子类的关系:
- 父类:基类(即被继承的类)
- 子类:派生类(即继承类)
- 重写:(即覆盖)
- 即子类对父类中属性和方法进行重写。
- 注意:子类重写属性、方法后,父类中的属性和方法仍然存在,仅仅在子类中被重写。
- 类方法的调用顺序:
- 先查询子类中的属性和方法,(若子类中不存在对应的属性和方法),再从父类中进行查询。
3、面向对象的多态
- 多态:
- 不同子类对象在调用相同的父类方法时,返回不同的执行结果。
- 【即不同对象调用相同的方法(接口)时,返回的结果不同。】
- 多态的本质:
- ①在子类中对父类属性和方法的重写 + ②定义一个公共方法(接口)。
- 注意:公共接口传入的值应为实例化后的对象。
4、补充:函数super()
- super方法:调用父类中的属性和方法。
python中的文件操作
1、文件中的基础知识
- 文件类型:
- 文本文件(.txt、.doc、.docx等)、图片文件(.png、.gif、.jpg等)、视频文件(.mp4、.mov等)、音频文件(.mp3、.ape、.wave等)、可执行文件(.exe、.sys、.dll、.bat等)等。
- 文件路径:
- 相对路径:当前文件与其他文件夹的路径关系。
- 绝对路径:(对于windows:)从盘符(C\D...)开始,到当前文件的路径。
- 编码
- 编码:将字符集中的字符转化为计算机可识别和处理的二进制数字的过程。
- 常见的编码方式:
- ASCII:7位二进制(128个字符)
- Unicode:16位二进制(65536个字符)
- UTF-8:(常用)
- GBK:汉字编码方式
2、文件打开与关闭
2.1、文件的打开
- 文件打开函数:open()
- open函数用于打开文件,函数调用成功后返回一个文件对象。
- open('文件名','文件打开方式','文件编码格式')
- 文件名:可用相对路径、也可用绝对路径的方式写入文件名。
- 文件打开方式:
- r:只读【默认】
- 注意:r模式下,操作的文件必须已经存在。
- w:只写
- 若文件存在,则对原文件内容进行覆盖。
- 若文件不存在,则自动创建。
- a:追加
- 若文件存在,则在文件末尾追加新内容。
- 若文件不存在,则自动创建。
- r+:读写
- 既可读、也可写。
- w+:读写
- 同r+
- a+:读、追加
- b:用于打开二进制文件
- r:只读【默认】
- 文件编码方式:【可写、可不写】
- 例如:可指定文件编码格式为utf-8
- encoding = "UTF-8"
2.2、文件的关闭
- 手动关闭文件:【减少对内存的占用】
- 文件对象名.close()
- 自动关闭文件:【程序执行完毕后,自动关闭文件】
- with关键词
- with open('文件名','文件打开方式','文件编码方式') as 文件对象名:
- # 文件操作
3、文件操作
- 格式:
- 文件对象名.文件操作方法
- 文件操作方法:
- read():读取文件中所有的内容,返回字符串。
- 也可指定一次读取的字节数:
- 例如:文件对象名.read(6) # 仅获取文件中前6个字节的数据。
- 也可指定一次读取的字节数:
- readlines():同read(),返回列表。
- readline():读取文件中的一行数据,返回字符串。
- tell():获取当前文件中,读写光标的位置。
- seek():设置当前文件中,读写光标的位置。
- read():读取文件中所有的内容,返回字符串。
4、目录操作
- 格式:
- import os # 导入os模块
- os.目录操作方法()
- 目录操作方法:
- getcwd():获取当前文件所在的目录(路径),返回绝对路径。
- mkdir():创建目录
- 例如:os.mkdir('aaa/bbb') # 在aaa目录下,创建bbb目录
- 注意:要求aaa目录必须事先存在,否则报错。
- 例如:os.mkdir('aaa/bbb') # 在aaa目录下,创建bbb目录
- rmdir():删除目录
- 例如:os.rmdir('aaa') # 删除aaa目录
- 注意:要求在aaa目录下,不能有其他子目录或文件,否则报错。
- 例如:os.rmdir('aaa') # 删除aaa目录
- listdir():获取某文件夹下的所有文件
- path.isabs():可以判断目标路径是否为绝对路径,若为绝对路径返回True,否则返回Faslse。
- path.abspath():目标路径为相对路径时,使用abspath()函数可将当前路径规范化为绝对路径。
- path.exists():os模块中的exists()函数用于判断路径是否存在,如果当前路径存在该函数返回True,否则返回False。
正则表达式
1、引入
- 正则表达式:是一个特殊的字符序列。
- 作用:过滤、筛选、匹配或查找符合某些规则的字符串。
- 多用于爬虫、数据抓取领域。
- 拓展:在多种语言中(Python、Java、PHP、JavaScript等),都支持正则表达式的使用。
2、re模块
re模块:用于使用正则表达式对字符串进行匹配。
2.1、match、search、findall方法的区别
- match:
- 语法:
- match(正则表达式pattern,待匹配的字符串string,标志位flags)
- 作用:
- 从字符串的起始位置开始,逐字符进行匹配,
- 若匹配成功,则返回一个匹配对象。
- 反之,返回None。
- 示例1:
- str1 = "python123java"
- print(re.match('123',str1)) # 返回None
- print(re.match('py',str1)) # 返回匹配成功后的对象
- 示例2:
- str2 = "123pythonjava"
- print(re.match('123',str2)) # 返回匹配成功后的对象
- print(re.match('py',str2)) # 返回None
- 语法:
- search:
- 语法:同match
- 作用:
- 扫描整个字符串,
- 若匹配成功,则返回第一个成功匹配的对象。
- 反之,返回None。
- 示例:
- str1 = "python123java"
- print(re.search('123',str1)) # 返回匹配成功后的对象
- print(re.search('py',str1)) # 返回匹配成功后的对象
- findall:
- 语法:同match
- 作用:
- 扫描整个字符串,
- 若匹配成功,则返回列表形式的所有成功匹配的内容。
- 反之,返回None。
- 示例:
- str3 = "python123java123"
- print(re.findall('123',str1)) # 返回列表['123','123']
- print(re.findall('py',str1)) # 返回列表['py']
3、正则表达式模式
3.1、匹配内容的设定
【即用特殊符号来匹配特定的字符。】
- .(点):
- 表示匹配任意1个字符(\n回车除外)
- [ ]:
- 匹配[ ]中列举的1个字符
- 例如:[abc]匹配a或b或c
- [^指定字符]:
- 匹配除了指定字符以外的所有字符
- 例如:[^abc]匹配除了a,b,c之外的字符
- \d:
- 匹配(1个)数字(0-9)
- \D:
- 匹配(1个)非数字
- \s:
- 匹配(1个)空白(即空格、tab键)
- \S
- 匹配(1个)非空白
- \w:
- 匹配(1个)非特殊字符(即a-z、A-Z、0-9、下划线_、汉字)
- \W:
- 匹配(1个)特殊字符(例如:!、@、#、$、%、^、&、*、.、:、"等)
3.2、(连续)出现次数的设定
【即设定某匹配字符出现的次数】
- *:匹配*前一个字符连续出现0次或者无数次。【可以为0次】
- +:匹配+前一个字符连续出现1次或者无数次。【至少有1次】
- ?:匹配?前一个字符连续出现0次或者1次。
- {m}:匹配{ }前一个字符连续出现m次。
- {m,}:匹配{ }前一个字符至少连续出现m次。
- {m,n}:匹配{ }前一个字符连续出现m到n次。
3.3、匹配顺序的设定
- ^:匹配字符串的开头
- $:匹配字符串的末尾
- 例如:
- ^1.*:表示以1开头(^1)的任意字符(.)且可以出现0次或无数次(*)。
- .*n$:表示以n结尾(n$)的任意字符(.)且可以出现0次或无数次(*)。
4、贪婪与非贪婪模式
- 贪婪模式:【+】
- 尽可能的匹配更多的字符。
- +:(连续)匹配1次或多次。
- 非贪婪模式:【?】
- 尽可能的匹配少的字符。
- ?:(连续)匹配0次或1次。
- 例如:
- str4 = "py123"
- print(re.search(r'py\d+',str4)) # 返回匹配成功的对象中match="py123"
- print(re.search(r'py\d?',str4)) # 返回匹配成功的对象中match="py1"
- 注意:上述使用r是为了避免转义字符进行转义。
异常的捕获
1、python中的异常
- BaseException【所有异常的父类】
- SystemExit (python解释器退出)
- KeyboardInterrupt (用户中断)
- GeneratorExit (生成器发生异常)
- Exception【常见异常的父类】
- IndexError
- NameError
- FileNotFoundError
- ZeroDivisionError
- SyntaxError(语法错误)
- 等等
2、捕获程序运行时的异常
- 引入:
- 将不确定的或可能出错的代码放入到try中,避免由于部分语句报错,而终止整个程序。
- try-except语句:
- 若try中的代码程序运行出错时(此时不终止整个程序),转而执行except中的代码。
- 拓展:except语句后,可添加Exception(常见异常的父类),用于打印输出报错的详细信息。
- except Exception as infoError:
- print(infoError)
- except Exception as infoError:
- try-except-finally语句:
- finally:不管try中的代码程序是否出错,都会执行finally中的代码。
3、闭包
- '函数名'与'函数名()'的区别:
- 函数名:指该函数的地址
- 函数名():指调用该函数
- 闭包的引入:
- 函数内部定义的变量为局部变量,只能在函数内部使用,当函数调用执行完毕后,局部变量自动销毁。
- 在函数外部无法获取函数内部的局部变量或内部函数。
- 因此,若想在外部对函数内部的局部变量或内部函数进行操作时,需使用闭包。
- 闭包的定义:
- 在函数的嵌套中(即函数中继续定义函数),内部函数使用了外部函数的变量或参数,且外部函数返回内部函数的地址(E.G、函数名)。
- 闭包的作用:可在函数外部对内部函数进行调用。
- 保存内部函数地址的变量名 = 外部函数名() # 外部函数执行后,返回内部函数的地址
- 保存内部函数地址的变量名() # 即调用内部函数
- 补充:
- 函数名():指调用执行某函数
- 函数名 :指某函数的地址
- 例如:
- # 闭包函数定义
- def func1(): # 外部函数func1()
- num1 = 1 # 变量num1
- def func2(): # 内部函数fun2()
- num2 = num1 + 1 # 内部函数func2()使用了外部函数func1()中的变量num1
- print(num2)
- return func2 # 外部函数func1()返回内部函数func2()的地址func2
- # 函数调用
- addrFunc2 = func1() # addrFunc2变量保存的是内部函数func2()的地址func2
- addrFunc2() # 调用执行内部函数func2()
4、装饰器
- 本质:是一个闭包函数,但可给函数添加额外功能(即在闭包函数的基础上,添加一些额外的功能)。
- 语法糖:
- 格式:@装饰器函数名
- 语法糖是python提供的装饰函数的一个写法
- 装饰器本质上就是一个事先写好的函数(功能),并将自己拥有的功能赋予给其他函数。