本篇为学习Langchain过程中用到的一篇资料,刚好可以用于学习python的基础知识【来自黑马课程】
一、Python 环境与程序运行
- Python 解释器:常用 CPython(官方默认),可通过命令行输入 python(Windows)/ python3(Linux/Mac)进入交互环境
- 程序运行方式:
- 交互环境:直接输入代码回车执行,适合简单测试
- 脚本文件:将代码写入 .py 后缀文件,命令行执行 python 文件名.py(Windows)/ python3 文件名.py(Linux/Mac)
- 注释:代码中不被执行的说明性文字,用于提高可读性
- 单行注释:以 # 开头,示例:# 这是一行单行注释
- 多行注释:用三个单引号 ’’’ 或三个双引号 """ 包裹,示例: ’’' 这是多行注释 第一行 第二行 ’’' """ 这也是多行注释 支持换行书写 """
二、变量与数据类型
- 变量定义:无需声明类型,直接赋值即可,变量名由字母、数字、下划线组成,不能以数字开头,区分大小写,不能使用Python关键字
- 赋值语法:变量名 = 赋值内容,示例:name = “Python”,age = 25,score = 98.5
- 多变量赋值:a, b, c = 1, 2, 3(一一对应);a = b = c = 10(所有变量赋同一值)
- 基本数据类型
- 数字类型(Number)
- 整数(int):正整数、负整数、0,示例:10,-5,0
- 浮点数(float):带小数点的数字,示例:3.14,-0.99,10.0
- 布尔值(bool):只有两个值 True(真,等价于1)和 False(假,等价于0),示例:is_ok = True,is_pass = False
- 复数(complex):形如 a+bj,示例:num = 3+4j
- 字符串类型(str):用单引号、双引号或三引号包裹的字符序列
- 示例:s1 = ‘hello’,s2 = “world”,s3 = ‘‘‘hello python’’’
- 字符串不可变:一旦创建,无法修改单个字符
- 容器类型(基础)
- 列表(list):有序、可变、可重复存储不同类型数据,用 [] 包裹,示例:lst = [1, “python”, 3.14, True]
- 元组(tuple):有序、不可变、可重复存储不同类型数据,用 () 包裹,示例:tup = (2, “java”, 9.9)
- 字典(dict):无序(Python3.7+默认有序)、可变,以键值对(key: value)存储,key唯一且不可变,用 {} 包裹,示例:dic = {“name”: “张三”, “age”: 20}
- 集合(set):无序、可变、不可重复存储数据,用 {} 包裹(空集合需用 set(),不能用 {}),示例:s = {1, 2, 3, 3}(最终为 {1,2,3})
- 数字类型(Number)
- 数据类型转换
- 转为整数:int(x),示例:int(“123”) → 123,int(3.99) → 3
- 转为浮点数:float(x),示例:float(“3.14”) → 3.14,float(10) → 10.0
- 转为字符串:str(x),示例:str(123) → “123”,str(True) → “True”
- 转为列表:list(x),示例:list((1,2,3)) → [1,2,3]
- 转为元组:tuple(x),示例:tuple([1,2,3]) → (1,2,3)
- 转为集合:set(x),示例:set([1,1,2]) → {1,2}
三、运算符
- 算术运算符:用于数值计算
- +:加法,示例:10 + 20 → 30;字符串/列表拼接,示例:“hello” + “world” → “helloworld”
- -:减法,示例:20 - 10 → 10
- *:乘法,示例:10 * 3 → 30;字符串/列表重复,示例:“ab” * 3 → “ababab”
- /:除法,结果为浮点数,示例:10 / 3 → 3.3333333333333335
- //:整除(向下取整),示例:10 // 3 → 3;-10 // 3 → -4
- %:取模(求余数),示例:10 % 3 → 1
- **:幂运算,示例:2 ** 3 → 8;10 ** 2 → 100
- 赋值运算符:用于给变量赋值
- =:基本赋值,示例:a = 10
- +=:加后赋值,示例:a += 5 等价于 a = a + 5
- -=:减后赋值,示例:a -= 5 等价于 a = a - 5
- *=:乘后赋值,示例:a *= 5 等价于 a = a * 5
- /=:除后赋值,示例:a /= 5 等价于 a = a / 5
- //=:整除后赋值,示例:a //= 5 等价于 a = a // 5
- %=:取模后赋值,示例:a %= 5 等价于 a = a % 5
- **=:幂后赋值,示例:a **= 5 等价于 a = a ** 5
- 比较运算符:用于比较两个值,结果为布尔值 True/False
- ==:等于,示例:10 == 10 → True;“abc” == “abd” → False
- !=:不等于,示例:10 != 20 → True
-
:大于,示例:20 > 10 → True
- <:小于,示例:10 < 20 → True
-
=:大于等于,示例:10 >= 10 → True;20 >= 15 → True
- <=:小于等于,示例:10 <= 20 → True;15 <= 15 → True
- 逻辑运算符:用于逻辑判断(与、或、非)
- and:逻辑与,所有条件为真才为真,有一个为假则为假,示例:(10 > 5) and (20 > 15) → True
- or:逻辑或,有一个条件为真就为真,所有条件为假才为假,示例:(10 > 5) or (20 < 15) → True
- not:逻辑非,取反,示例:not (10 > 5) → False
- 成员运算符:用于判断元素是否在容器中(列表、元组、字符串、集合、字典)
- in:判断元素是否存在,示例:“a” in “abc” → True;1 in [1,2,3] → True
- not in:判断元素是否不存在,示例:“d” not in “abc” → True;4 not in [1,2,3] → True
- 身份运算符:用于判断两个变量是否指向同一个内存对象
- is:判断是否为同一对象,示例:a = 10; b = 10; a is b → True
- is not:判断是否不是同一对象,示例:a = [1,2]; b = [1,2]; a is not b → True
四、流程控制语句
- 条件判断语句(if-elif-else):根据条件执行不同代码块
- 基本语法1(单条件): if 条件表达式: 缩进的执行代码块(条件为True时执行) (注意:Python用缩进区分代码块,通常4个空格,不要混用空格和Tab)
- 示例: if score >= 60: print(“及格”)
- 基本语法2(双条件): if 条件表达式1: 缩进的执行代码块1 else: 缩进的执行代码块2(条件表达式1为False时执行)
- 示例: if score >= 60: print(“及格”) else: print(“不及格”)
- 基本语法3(多条件): if 条件表达式1: 缩进的执行代码块1 elif 条件表达式2: 缩进的执行代码块2 elif 条件表达式3: 缩进的执行代码块3 … else: 缩进的执行代码块n(所有前面条件都为False时执行)
- 示例: if score >= 90: print(“优秀”) elif score >= 80: print(“良好”) elif score >= 60: print(“及格”) else: print(“不及格”)
- 嵌套条件:if语句内部可以嵌套if-elif-else,注意缩进层级 if a > 10: if a < 20: print(“a在10和20之间”) else: print(“a大于等于20”) else: print(“a小于等于10”)
- 循环语句:重复执行某段代码块
- for 循环:用于遍历可迭代对象(列表、元组、字符串、字典等)
- 基本语法: for 变量名 in 可迭代对象: 缩进的循环执行代码块
- 示例1(遍历列表): lst = [1,2,3,4] for num in lst: print(num)
- 示例2(遍历字符串): s = “python” for char in s: print(char)
- 示例3(range() 函数辅助:生成整数序列,range(start, end, step),start默认0,step默认1,不包含end) for i in range(5): # 0,1,2,3,4 print(i) for i in range(2, 8): # 2,3,4,5,6,7 print(i) for i in range(0, 10, 2): # 0,2,4,6,8 print(i)
- 示例4(遍历字典): dic = {“name”: “张三”, “age”: 20} for key in dic: # 遍历键 print(key) for value in dic.values(): # 遍历值 print(value) for key, value in dic.items(): # 遍历键值对 print(key, value)
- while 循环:根据条件判断是否继续循环,先判断条件,再执行代码块
- 基本语法: while 条件表达式: 缩进的循环执行代码块 (注意:需设置循环终止条件,避免无限循环)
- 示例1(基本循环): count = 0 while count < 5: print(count) count += 1 # 终止条件:count递增到5,条件不成立
- 示例2(无限循环,需用break终止): while True: s = input(“输入内容(输入quit退出):”) if s == “quit”: break print(“你输入了:”, s)
- 循环控制语句:
- break:立即终止当前循环,跳出循环体,不再执行后续循环代码 示例: for i in range(10): if i == 5: break print(i) # 输出0,1,2,3,4
- continue:跳过当前循环的剩余代码,直接进入下一次循环 示例: for i in range(10): if i == 5: continue print(i) # 输出0,1,2,3,4,6,7,8,9
- else:循环正常结束(未被break终止)时,执行else代码块 示例: for i in range(5): print(i) else: print(“循环正常结束”)
- for 循环:用于遍历可迭代对象(列表、元组、字符串、字典等)
五、字符串操作
- 字符串索引与切片:索引用于获取单个字符,切片用于获取子字符串
- 索引:分为正向索引(从0开始,从左到右)和反向索引(从-1开始,从右到左) 示例:s = “python” s[0] → “p”(正向索引第1个字符) s[-1] → “n”(反向索引第1个字符) s[3] → “h”;s[-3] → “h”
- 切片语法:字符串[start:end:step],start默认0,end默认字符串长度,step默认1,不包含end对应的字符 示例:s = “python” s[0:3] → “pyt”(从索引0到2) s[2:] → “thon”(从索引2到末尾) s[:4] → “pyth”(从开头到索引3) s[1:5:2] → “yh”(从索引1到4,步长2) s[::-1] → “nohtyp”(反转字符串)
- 常用字符串方法
- len(s):获取字符串长度,示例:len(“python”) → 6
- s.lower():转为全小写,示例:“Python”.lower() → “python”
- s.upper():转为全大写,示例:“Python”.upper() → “PYTHON”
- s.strip():去除字符串首尾空格(可指定去除的字符),示例:" hello “.strip() → “hello”;”###python###".strip("#") → “python”
- s.split(sep):按指定分隔符分割字符串,返回列表,示例:“a,b,c”.split(",") → [“a”,“b”,“c”];“hello world”.split() → [“hello”,“world”]
- s.join(iter):用字符串连接可迭代对象中的元素,示例:",".join([“a”,“b”,“c”]) → “a,b,c”
- s.replace(old, new):替换字符串中的旧字符/子串为新字符/子串,示例:“hello world”.replace(“world”, “python”) → “hello python”
- s.find(sub):查找子串首次出现的索引,未找到返回-1,示例:“python”.find(“th”) → 2
- s.count(sub):统计子串出现的次数,示例:“ababab”.count(“ab”) → 3
- s.startswith(prefix):判断字符串是否以指定前缀开头,返回布尔值,示例:“python”.startswith(“py”) → True
- s.endswith(suffix):判断字符串是否以指定后缀结尾,返回布尔值,示例:“python”.endswith(“on”) → True
六、列表操作
- 列表索引与切片:与字符串用法一致,列表切片返回新列表,支持修改
- 索引:lst = [1,2,3,4,5] lst[0] → 1;lst[-1] → 5
- 切片:lst[1:4] → [2,3,4];lst[::-1] → [5,4,3,2,1]
- 切片修改:lst[1:3] = [6,7] → lst变为 [1,6,7,4,5]
- 常用列表方法
- len(lst):获取列表长度,示例:len([1,2,3]) → 3
- lst.append(x):在列表末尾添加一个元素,示例:lst = [1,2];lst.append(3) → [1,2,3]
- lst.extend(iter):在列表末尾扩展可迭代对象的元素,示例:lst = [1,2];lst.extend([3,4]) → [1,2,3,4]
- lst.insert(index, x):在指定索引位置插入元素,示例:lst = [1,3];lst.insert(1, 2) → [1,2,3]
- lst.remove(x):删除列表中首次出现的指定元素,示例:lst = [1,2,3,2];lst.remove(2) → [1,3,2]
- lst.pop(index):删除指定索引位置的元素,默认删除最后一个元素,返回被删除的元素,示例:lst = [1,2,3];lst.pop() → 3,lst变为 [1,2]
- lst.clear():清空列表所有元素,示例:lst = [1,2,3];lst.clear() → []
- lst.index(x):查找元素首次出现的索引,未找到报错,示例:[1,2,3].index(2) → 1
- lst.count(x):统计元素出现的次数,示例:[1,2,2,3].count(2) → 2
- lst.sort():对列表元素进行升序排序(原地修改),示例:lst = [3,1,2];lst.sort() → [1,2,3]
- lst.reverse():反转列表元素(原地修改),示例:lst = [1,2,3];lst.reverse() → [3,2,1]
七、字典操作
- 字典的键值对访问与修改
- 访问值:通过键访问,语法:dic[key],示例:dic = {“name”: “张三”};dic[“name”] → “张三”
- 修改值:通过键修改,语法:dic[key] = new_value,示例:dic[“name”] = “李四” → dic变为 {“name”: “李四”}
- 添加键值对:语法:dic[new_key] = value,示例:dic[“age”] = 20 → dic变为 {“name”: “李四”, “age”: 20}
- 常用字典方法
- len(dic):获取字典键值对的个数,示例:len({“name”: “张三”, “age”: 20}) → 2
- dic.keys():返回所有键的可迭代对象,示例:dic.keys() → dict_keys([’name’, ‘age’])
- dic.values():返回所有值的可迭代对象,示例:dic.values() → dict_values([‘张三’, 20])
- dic.items():返回所有键值对的可迭代对象,示例:dic.items() → dict_items([(’name’, ‘张三’), (‘age’, 20)])
- dic.get(key, default):获取键对应的值,键不存在返回默认值(默认None),示例:dic.get(“name”) → “张三”;dic.get(“gender”, “未知”) → “未知”
- dic.pop(key, default):删除指定键的键值对,返回对应的值,键不存在返回默认值(不指定则报错),示例:dic.pop(“age”) → 20
- dic.clear():清空字典所有键值对,示例:dic.clear() → {}
- dic.update(new_dic):用新字典更新原字典,存在的键覆盖值,不存在的键添加,示例:dic.update({“age”: 21, “gender”: “男”})
八、函数
- 函数定义与调用
- 定义语法: def 函数名(参数列表): 缩进的函数体代码块 [return 返回值] (说明:def是关键字,函数名遵循变量命名规则,参数列表可选,return可选,无return默认返回None)
- 示例1(无参数无返回值): def say_hello(): print(“Hello Python!”)
- 示例2(有参数有返回值): def add(a, b): result = a + b return result
- 函数调用:语法:函数名(参数列表),示例: say_hello() # 调用无参函数 sum_result = add(10, 20) # 调用有参函数,接收返回值 print(sum_result)
- 函数参数
- 位置参数:按参数定义顺序传递参数,必须一一对应,个数一致,示例:add(10, 20)(10对应a,20对应b)
- 关键字参数:按参数名传递参数,顺序可打乱,示例:add(b=20, a=10)
- 默认参数:定义函数时给参数指定默认值,调用时可省略该参数(使用默认值),示例: def power(x, n=2): return x ** n power(3) → 9(使用默认n=2) power(3, 3) → 27(覆盖默认值)
- 可变参数:
- *args:接收任意个数的位置参数,打包为元组,示例: def sum_all(*args): total = 0 for num in args: total += num return total sum_all(1,2,3) → 6;sum_all(1,2,3,4,5) → 15
- **kwargs:接收任意个数的关键字参数,打包为字典,示例: def print_info(**kwargs): for key, value in kwargs.items(): print(key, “:”, value) print_info(name=“张三”, age=20)
- return 语句:用于返回函数执行结果,执行到return后函数立即结束,可返回单个值或多个值(多个值打包为元组) 示例: def func(): return 1, 2, 3 # 等价于 return (1,2,3) a, b, c = func() # 解包,a=1, b=2, c=3
九、模块与包
- 模块:一个 .py 文件就是一个模块,用于封装相关的变量、函数、类等,提高代码复用性
- 导入模块:
- import 模块名,示例:import math(导入数学模块)
- 导入模块并指定别名,示例:import math as m(别名m,简化使用)
- 从模块中导入指定内容,示例:from math import pi, sqrt(导入pi和sqrt函数)
- 从模块中导入所有内容,示例:from math import *(不推荐,容易出现命名冲突)
- 使用模块中的内容:
- 导入整个模块:模块名.变量/函数,示例:math.pi → 3.141592653589793;math.sqrt(16) → 4.0
- 导入指定内容:直接使用变量/函数,示例:pi → 3.141592653589793;sqrt(16) → 4.0
- 导入模块:
- 包:包含 init.py 文件的文件夹,用于组织多个相关模块,避免模块名冲突
- 导入包中的模块:
- import 包名.模块名
- from 包名 import 模块名
- from 包名.模块名 import 函数/变量
- 导入包中的模块:
十、异常处理
- 异常:程序运行过程中出现的错误(如语法错误、索引越界、键不存在等),未处理会导致程序终止
- 异常处理语法(try-except-else-finally): try: 缩进的可能出现异常的代码块 except 异常类型1: 缩进的异常1处理代码块 except 异常类型2: 缩进的异常2处理代码块 except: 缩进的所有未捕获异常的处理代码块(万能异常捕获) else: 缩进的try代码块无异常时执行的代码块 finally: 缩进的无论是否出现异常都必须执行的代码块(如资源释放)
- 示例: try: a = 10 / int(input(“请输入一个数字:”)) except ZeroDivisionError: print(“错误:不能除以0”) except ValueError: print(“错误:请输入有效的整数”) else: print(“计算结果:”, a) finally: print(“程序执行完毕”)
十一、文件操作
- 文件打开与关闭
- 打开文件:open() 函数,语法:file_obj = open(file_path, mode, encoding=None)
- file_path:文件路径(绝对路径或相对路径)
- mode:打开模式,常用: r:只读模式(默认),文件不存在报错 w:写入模式,文件不存在创建,文件存在清空原有内容 a:追加模式,文件不存在创建,文件存在在末尾追加内容 r+:读写模式,文件不存在报错 w+:读写模式,文件不存在创建,文件存在清空原有内容 a+:读写模式,文件不存在创建,文件存在在末尾追加内容 带 b 的模式(如 rb、wb):二进制模式,用于读写图片、视频等二进制文件,无需指定 encoding
- encoding:文件编码,常用 utf-8,示例:encoding=“utf-8”
- 关闭文件:file_obj.close(),必须关闭文件以释放系统资源
- 打开文件:open() 函数,语法:file_obj = open(file_path, mode, encoding=None)
- 文件读写操作
- 读取文件:
- file_obj.read(size):读取指定字节数(size可选,默认读取全部内容)
- file_obj.readline():读取一行内容
- file_obj.readlines():读取所有行,返回列表,每行作为一个元素
- 写入文件:
- file_obj.write(content):写入指定内容(字符串或二进制数据)
- file_obj.writelines(list):写入列表中的所有元素(元素需为字符串)
- 读取文件:
- 上下文管理器(with 语句):自动关闭文件,无需手动调用 close(),推荐使用 示例1(读取文件): with open(“test.txt”, “r”, encoding=“utf-8”) as f: content = f.read() print(content) 示例2(写入文件): with open(“test.txt”, “w”, encoding=“utf-8”) as f: f.write(“Hello Python!\n”) f.writelines([“第一行\n”, “第二行\n”]) 示例3(追加文件): with open(“test.txt”, “a”, encoding=“utf-8”) as f: f.write(“这是追加的内容”)
Python 高级语法(纯文本格式,可直接复制保存为TXT)
十二、面向对象编程(OOP)
-
类与对象的基本概念
- 类(class):是对象的抽象模板,定义了对象的属性和方法
- 对象:是类的实例,通过类创建具体的对象
- 语法: class 类名:
类属性:属于类本身,所有实例共享
类属性名 = 属性值
初始化方法:创建对象时自动调用,用于初始化对象属性
def init(self, 参数列表): # 实例属性:属于单个对象,每个实例独立拥有 self.实例属性名 = 参数值
实例方法:第一个参数必须是self,代表当前对象
def 方法名(self, 参数列表): 方法体代码
类方法:第一个参数必须是cls,代表类本身,用@classmethod装饰
@classmethod def 类方法名(cls, 参数列表): 方法体代码
静态方法:无默认参数,和类、对象无关,用@staticmethod装饰
@staticmethod def 静态方法名(参数列表): 方法体代码
- 示例: class Person:
类属性
species = “人类”
初始化方法
def init(self, name, age): self.name = name # 实例属性 self.age = age
实例方法
def introduce(self): print(f"我叫{self.name},今年{self.age}岁")
类方法
@classmethod def get_species(cls): return cls.species
静态方法
@staticmethod def is_adult(age): return age >= 18
创建对象(实例化)
p1 = Person(“张三”, 20) p2 = Person(“李四”, 17)
访问实例属性和方法
print(p1.name) # 输出 张三 p1.introduce() # 输出 我叫张三,今年20岁
访问类属性和类方法
print(Person.species) # 输出 人类 print(Person.get_species()) # 输出 人类
调用静态方法
print(Person.is_adult(20)) # 输出 True print(Person.is_adult(17)) # 输出 False
-
三大特性:封装、继承、多态
- 封装:隐藏对象的属性和方法,仅通过公开接口访问,提高安全性
- 私有属性/方法:在名称前加两个下划线__,只能在类内部访问
- 示例: class Student: def init(self, name, score): self.name = name self.__score = score # 私有属性
def get_score(self): # 公开接口获取私有属性 return self.__score
def set_score(self, new_score): # 公开接口修改私有属性,可添加校验 if 0 <= new_score <= 100: self.__score = new_score else: print(“分数必须在0-100之间”)
- 封装:隐藏对象的属性和方法,仅通过公开接口访问,提高安全性
s = Student(“王五”, 90) print(s.get_score()) # 输出 90 s.set_score(95) print(s.get_score()) # 输出 95 s.set_score(101) # 输出 分数必须在0-100之间
- 继承:子类继承父类的属性和方法,实现代码复用,子类可扩展或重写父类方法
- 语法:class 子类名(父类名):
- 重写:子类定义和父类同名的方法,覆盖父类方法
- super():调用父类的方法,常用于子类初始化
- 示例:
父类
class Animal: def init(self, name): self.name = name
def run(self):
print(f"{self.name}在奔跑")
子类继承父类
class Dog(Animal): # 重写父类方法 def run(self): print(f"{self.name}在飞快地奔跑")
# 子类扩展方法
def bark(self):
print(f"{self.name}在叫")
class Cat(Animal): def init(self, name, color): super().init(name) # 调用父类初始化方法 self.color = color # 子类新增属性
def run(self):
print(f"{self.color}的{self.name}在轻盈地奔跑")
dog = Dog(“旺财”) dog.run() # 输出 旺财在飞快地奔跑 dog.bark() # 输出 旺财在叫
cat = Cat(“咪咪”, “白色”) cat.run() # 输出 白色的咪咪在轻盈地奔跑
- 多态:不同子类对象调用同名方法,表现出不同行为,依赖于继承和方法重写
- 示例:
def animal_run(animal): animal.run()
animal_run(Dog(“旺财”)) # 输出 旺财在飞快地奔跑 animal_run(Cat(“咪咪”, “白色”)) # 输出 白色的咪咪在轻盈地奔跑
-
特殊方法(魔术方法)
- 以双下划线__开头和结尾,在特定场景自动调用
- 常用特殊方法:
- init:初始化对象
- str:打印对象时调用,返回字符串,示例: class Book: def init(self, title): self.title = title
def str(self): return f"书名:{self.title}"
b = Book(“Python编程”) print(b) # 输出 书名:Python编程 - repr:控制台输出对象时调用,用于调试 - len:调用len()函数时触发,示例: class MyList: def init(self, data): self.data = data
def __len__(self):
return len(self.data)
ml = MyList([1,2,3]) print(len(ml)) # 输出 3 - add:调用+运算符时触发,实现对象相加,示例: class Point: def init(self, x, y): self.x = x self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
p1 = Point(1,2) p2 = Point(3,4) p3 = p1 + p2 print(p3.x, p3.y) # 输出 4 6
十三、装饰器
- 概念:装饰器是一个函数,用于增强另一个函数的功能,不修改原函数代码,遵循开放封闭原则
- 基础语法:
- 定义装饰器函数:接收被装饰函数作为参数,返回一个包装函数
- 使用@装饰器名 语法,放在被装饰函数定义上方
- 示例1(无参数装饰器):
定义装饰器:计算函数执行时间
import time def timer_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) # 执行原函数 end_time = time.time() print(f"{func.name}执行时间:{end_time - start_time}秒") return result return wrapper
使用装饰器
@timer_decorator def my_func(): time.sleep(1) print(“函数执行完成”)
my_func() # 输出 函数执行完成 + 执行时间
- 示例2(带参数装饰器):需要嵌套三层函数,最外层函数接收装饰器参数
def repeat_decorator(num): def decorator(func): def wrapper(*args, **kwargs): for _ in range(num): result = func(*args, **kwargs) return result return wrapper return decorator
使用带参数装饰器
@repeat_decorator(3) def say_hi(): print(“Hi!”)
say_hi() # 连续输出3次 Hi!
-
常用内置装饰器:
- @classmethod:定义类方法
- @staticmethod:定义静态方法
- @property:将方法转换为属性,调用时无需加括号,示例: class Person: def init(self, name, age): self.name = name self.__age = age
@property def age(self): return self.__age
@age.setter def age(self, new_age): if 0 <= new_age <= 120: self.__age = new_age else: print(“年龄不合法”)
p = Person(“张三”, 20) print(p.age) # 调用@property装饰的方法,无需括号,输出20 p.age = 25 # 调用@age.setter装饰的方法,修改属性 print(p.age) # 输出25
十四、迭代器与生成器
- 迭代器
- 可迭代对象(Iterable):能被for循环遍历的对象,如列表、字符串、字典等,实现了__iter__方法
- 迭代器(Iterator):实现了__iter__和__next__方法的对象,调用next()函数获取下一个元素,无元素时抛出StopIteration异常
- 转换方法:使用iter()函数将可迭代对象转为迭代器
- 示例: lst = [1,2,3] it = iter(lst) # 转为迭代器 print(next(it)) # 输出1 print(next(it)) # 输出2 print(next(it)) # 输出3
print(next(it)) # 抛出StopIteration异常
- 自定义迭代器:
class MyIterator: def init(self, max_num): self.max_num = max_num self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max_num:
self.current += 1
return self.current
else:
raise StopIteration
mi = MyIterator(3) for num in mi: print(num) # 输出1 2 3
- 生成器
- 概念:是一种特殊的迭代器,通过yield关键字定义,无需手动实现__iter__和__next__方法,更简洁
- 工作原理:调用生成器函数时,函数不会立即执行,返回生成器对象;每次调用next()或for循环时,执行到yield暂停,返回yield后的值,下次从暂停处继续执行
- 示例1(生成器函数): def my_generator(max_num): current = 1 while current <= max_num: yield current # 暂停并返回值 current += 1
gen = my_generator(3) print(next(gen)) # 输出1 print(next(gen)) # 输出2 print(next(gen)) # 输出3
- 示例2(生成器表达式):语法类似列表推导式,用()代替[],节省内存(无需一次性生成所有元素)
gen_expr = (x*2 for x in range(3)) for num in gen_expr: print(num) # 输出0 2 4
十五、上下文管理器
-
概念:用于管理资源(如文件、网络连接、数据库连接),确保资源使用后自动释放,避免资源泄漏
-
实现方式
- 方式1:类实现__enter__和__exit__方法
- enter:进入上下文时调用,返回资源对象
- exit:退出上下文时调用,处理异常和资源释放
- 示例: class MyFile: def init(self, file_path, mode): self.file_path = file_path self.mode = mode self.file = None
def enter(self): self.file = open(self.file_path, self.mode, encoding=“utf-8”) return self.file
def exit(self, exc_type, exc_val, exc_tb): if self.file: self.file.close() # 返回True可抑制异常,返回False则抛出异常 return False
- 方式1:类实现__enter__和__exit__方法
使用自定义上下文管理器
with MyFile(“test.txt”, “w”) as f: f.write(“Hello 上下文管理器”)
- 方式2:使用contextlib模块的@contextmanager装饰器,通过生成器函数实现,更简洁
from contextlib import contextmanager
@contextmanager def my_open(file_path, mode): f = open(file_path, mode, encoding=“utf-8”) try: yield f # yield之前是__enter__逻辑,之后是__exit__逻辑 finally: f.close()
with my_open(“test.txt”, “r”) as f: print(f.read())
十六、多线程与多进程
- 多线程:适用于IO密集型任务(如文件读写、网络请求),Python中受GIL(全局解释器锁)限制,同一时间只有一个线程执行Python字节码
- 使用threading模块
- 示例: import threading import time
def task(name): print(f"任务{name}开始") time.sleep(2) # 模拟IO操作 print(f"任务{name}结束")
创建线程
t1 = threading.Thread(target=task, args=(“A”,)) t2 = threading.Thread(target=task, args=(“B”,))
启动线程
t1.start() t2.start()
等待线程结束
t1.join() t2.join() print(“所有任务完成”)
- 多进程:适用于CPU密集型任务(如数值计算),不受GIL限制,通过multiprocessing模块实现
- 示例: from multiprocessing import Process import time
def task(name): print(f"任务{name}开始") time.sleep(2) print(f"任务{name}结束")
if name == “main”: # Windows系统必须加此判断 p1 = Process(target=task, args=(“A”,)) p2 = Process(target=task, args=(“B”,))
p1.start()
p2.start()
p1.join()
p2.join()
print("所有任务完成")
十七、正则表达式
- 概念:用于匹配、查找、替换字符串的模式,通过re模块实现
- 常用函数
- re.match(pattern, string):从字符串开头匹配,匹配成功返回匹配对象,否则返回None
- re.search(pattern, string):扫描整个字符串,找到第一个匹配项
- re.findall(pattern, string):找到所有匹配项,返回列表
- re.sub(pattern, repl, string):替换所有匹配的子串
- 常用元字符
- .:匹配任意单个字符(除换行符\n)
- ^:匹配字符串开头
- $:匹配字符串结尾
- *:匹配前一个字符0次或多次
- +:匹配前一个字符1次或多次
- ?:匹配前一个字符0次或1次
- []:匹配括号内任意一个字符
- \d:匹配数字,等价于[0-9]
- \w:匹配字母、数字、下划线,等价于[a-zA-Z0-9_]
- \s:匹配空白字符(空格、制表符、换行符等)
- 示例: import re
匹配手机号(11位数字,以1开头)
pattern = r"^1\d{10}$" print(re.match(pattern, “13812345678”)) # 匹配成功 print(re.match(pattern, “1234567890”)) # 匹配失败
提取所有数字
string = “年龄:20,身高:180cm” print(re.findall(r"\d+", string)) # 输出 [‘20’, ‘180’]
替换敏感词
string = “这个产品真垃圾” print(re.sub(r"垃圾", “”, string)) # 输出 这个产品真
十八、高级数据结构
-
集合(Set)的高级操作
- 交集:s1 & s2 或 s1.intersection(s2)
- 并集:s1 | s2 或 s1.union(s2)
- 差集:s1 - s2 或 s1.difference(s2)
- 对称差集:s1 ^ s2 或 s1.symmetric_difference(s2)
- 示例: s1 = {1,2,3} s2 = {3,4,5} print(s1 & s2) # 交集 {3} print(s1 | s2) # 并集 {1,2,3,4,5} print(s1 - s2) # 差集 {1,2}
-
有序字典(OrderedDict):Python3.7前字典无序,需用collections.OrderedDict保证插入顺序
- 示例: from collections import OrderedDict od = OrderedDict() od[“a”] = 1 od[“b”] = 2 od[“c”] = 3 for k, v in od.items(): print(k, v) # 按插入顺序输出 a 1, b 2, c 3
-
计数器(Counter):用于统计可迭代对象中元素的出现次数,返回字典格式
- 示例: from collections import Counter lst = [1,2,2,3,3,3] cnt = Counter(lst) print(cnt) # 输出 Counter({3: 3, 2: 2, 1: 1}) print(cnt.most_common(2)) # 输出出现次数最多的2个元素 [(3, 3), (2, 2)]
-
命名元组(namedtuple):创建有名称字段的元组,可读性更高
- 示例: from collections import namedtuple Point = namedtuple(“Point”, [“x”, “y”]) p = Point(1, 2) print(p.x) # 输出1 print(p.y) # 输出2
-
双端队列(deque):高效实现两端添加和删除元素,比列表更高效,适用于队列和栈场景
- 示例: from collections import deque dq = deque([1,2,3]) dq.append(4) # 右端添加 dq.appendleft(0) # 左端添加 print(dq) # 输出 deque([0, 1, 2, 3, 4]) dq.pop() # 右端删除 dq.popleft() # 左端删除 print(dq) # 输出 deque([1, 2, 3])