Python基础技术
语言概述与特点
动态语言特性与解释型语言的优劣
动态语言(如Python、JavaScript)和解释型语言(如Python、Ruby)是两个相关但不同的概念:动态语言强调类型检查在运行时进行,变量类型可动态变更;解释型语言强调无需预先编译为机器码,由解释器逐行执行。两者常重叠(如Python既是动态语言也是解释型语言),其优劣势可分别总结如下:
动态语言特性的核心特点:变量无强制类型声明,类型检查在运行时进行,支持动态修改对象结构(如添加属性/方法)。
动态语言特性的优势:
开发效率高:无需写类型声明,代码更简洁,适合快速迭代和原型开发(如Python一行代码实现复杂功能)。
灵活性强:可动态调整变量类型和对象结构,适配多变的业务需求(如JavaScript中对象可随时添加属性)。
学习门槛低:语法更接近自然语言,初学者易上手。
动态语言特性的劣势:
运行时错误风险高:类型错误(如字符串与数字相加)只能在运行时发现,可能导致线上故障。
性能损耗:运行时类型检查增加额外计算开销,执行效率通常低于静态类型语言(如Java、C#)。
重构难度大:大型项目中,类型不明确可能导致修改一处代码引发连锁错误,维护成本高。
解释型语言的核心特点:源代码直接由解释器逐行解析执行,无需编译为机器码(或仅进行部分即时编译)。
解释型语言的优势:
跨平台性好:依赖解释器而非底层机器码,一次编写可在多平台运行(如Python代码在Windows/Linux上无需修改)。
开发周期短:修改代码后无需重新编译,可立即运行,适合快速测试和调试。
部署简单:直接部署源代码,无需处理编译后的二进制文件,降低环境配置复杂度。
6. 解释型语言的劣势:
执行速度较慢:逐行解释比编译型语言(如C、Go)的预编译机器码执行效率低(尤其计算密集型任务)。
依赖解释器:运行环境必须安装对应解释器,增加部署依赖。
代码保密性差:源代码直接暴露,不如编译型语言的二进制文件难以逆向。
总结: 动态语言和解释型语言的优势集中在开发效率、灵活性和跨平台性,适合快速开发、脚本任务、Web应用等场景;劣势则体现在运行效率、错误检查和大型项目维护,因此在高性能、高可靠性要求的场景(如操作系统、实时系统)中,静态编译型语言(如C、Rust)仍占主导。
跨平台能力与丰富的标准库
跨平台:Python代码能在Windows、Linux、macOS等系统上直接运行,解释器会处理不同系统的差异,实现"一次编写,到处运行"。
标准库丰富:自带大量模块,涵盖文件操作、网络通信、数据处理等功能,无需额外安装就能完成多数任务,即"电池已包含"理念。
应用领域(Web开发、数据分析、人工智能等)
数据分析与科学计算:借助Pandas、NumPy等库处理数据,Matplotlib、Seaborn可视化数据,是科研和商业分析的常用工具。
人工智能与机器学习:TensorFlow、PyTorch等主流框架基于Python,广泛用于图像识别、自然语言处理等AI任务。
Web开发:Django、Flask等框架简化网站搭建,豆瓣、Instagram等均采用Python开发。
自动化运维与脚本:用于编写批量处理脚本、自动化测试、服务器管理等,提高运维效率。
爬虫开发:通过Requests、Scrapy等库抓取网页数据,应用于信息聚合、数据分析等场景。
教育领域:语法简单易懂,是初学者入门编程的首选语言,也常用于高校计算机课程。
游戏开发:可用于游戏脚本编写(如《文明IV》)、游戏测试等环节。
嵌入式系统与物联网:在树莓派等平台上,用于控制硬件、开发物联网应用。
以上只是Python的一部分功能,请记住“Python无所不能”,剩下的功能请在后续的学习探索中慢慢发掘吧
开发环境搭建
Python解释器安装
安装Python解释器的步骤简单直观,以下是主流系统的安装方法:
Windows系统:
访问官网:https://www.python.org/downloads/,点击"Download Python X.X.X"(X为最新版本)
运行安装包,勾选"Add Python to PATH"(关键,自动配置环境变量)
点击"Install Now",等待完成即可
macOS系统:
方法1:官网下载对应版本的.pkg安装包,双击安装
方法2:通过Homebrew(包管理工具)安装,终端输入:
brew install python3
Linux系统:
多数Linux(如Ubuntu)预装Python,终端输入
python3可查看版本如需安装/更新,终端输入:
sudo apt install python3(Debian/Ubuntu)或sudo yum install python3(CentOS)
验证安装:
安装完成后,打开终端(Windows用命令提示符或PowerShell),输入python(Windows)或python3(macOS/Linux),出现Python版本信息即成功。
如需退出解释器,输入exit()或按Ctrl+Z(Windows)/Ctrl+D(macOS/Linux)。
常用IDE推荐(PyCharm、VS Code)
请自行搜寻下载教程
第一个Python程序:Hello World
print('helloworld')基础语法结构
变量命名规范与动态类型
变量命名规范:
变量名必须以字母或下划线开头,不能以数字开头。
只能包含字母、数字和下划线。
避免使用编程语言的关键字。
使用描述性名称:变量名应反映其用途。
动态类型 :
动态类型是指在程序运行时才确定变量类型的特性。与静态类型不同,动态类型允许变量在运行时改变类型。其核心特点有:
变量无需声明类型:直接赋值即可
类型可以动态改变:同一个变量可以存储不同类型的数据。
运行时类型检查:错误(如类型不匹配)通常在运行时被发现。
#动态类型示例
variable = 10 # 初始为整数类型
print(type(variable)) # 输出: <class 'int'>
variable = "hello" # 运行时改变为字符串类型
print(type(variable)) # 输出: <class 'str'>
#尝试操作可能引发运行时错误
try:
result = variable + 5 # 字符串和整数相加,会报错
except TypeError as e:
print(f"错误: {e}") # 输出: 错误: can only concatenate str (not "int") to str
基本数据类型(int, float, str, bool)
1.查询数据类型:type(数据名)
2.数据类型:
2.1数值类型
2.1.1整数类型:
2.1.2浮点数类型:
浮点型运算:有一定概率运算后增加一些不确定的尾数,可以利用round函数保留所需要的位数。
print(0.1+0.2) #输出结果是0.30000000000000004
print(round(0.1+0.2,1)) #输出结果是0.3
print(round(0.52+0.1314,3)) #输出结果为0.651
print(round(0.52+0.1314,1)) #输出结果为0.7
print(round(0.7)) #输出结果为1 round函数在处理以5结尾的数字时采用的是银行家算法,即当一个数字恰好以5结尾时,会将其舍入到最接近的偶数。如,print(round(2.5)),其输出结果为2
2.1.3复数类型:
复数是由实数部分和虚数部分组成的数,通常表示为 a + bi 的形式
x=123+456j
print('实数部分为:',x.real)
print('虚数部分为:',x.image)2.2字符串类型
2.2.1转义字符:
2.2.2字符串的索引与切片:
s='helloworld'
print(s[0],s[-10],s[4]) #输出结果为h h o
print(s[2:7],s[-8:-3]) #输出结果为llowo llowo
print(s[:5],s[5:]) #输出结果为hello world2.2.3操作符:
2.2.4算数运算符:
2.3布尔类型
布尔类型是用来表示真值或者假值的数据类型。在Python中用True和False表示,其中True表示整数1,False表示整数0。
3.数据类相间的转换
函数作用:
流程控制语句
条件语句(if-elif-else结构与三元表达式以及模式匹配)
1. if-elif-else结构
num=eval(input('请输入密码:'))
if num==5201314:
print('密码正确,你好先生')
elif num==5211314:
print('密码正确,你好女士')
else:
print('密码错误')2. 三元表达式
在Python中,三元表达式可以被看作是if-else语句的简化版本。
num=eval(input('请输入密码:'))
print('密码正确,你好先生')if num==5201314 else(print('密码正确,你好女士')if num==5211314 else print('密码错误'))从代码复杂度上来看三元表达式显然更简洁。然而,这并不意味着任何情况下都应该使用三元表达式。如果条件或者返回值的计算逻辑很复杂,那么使用if-else语句可能会更好,因为它的结构更清晰,更易于理解。
3. 模式匹配
score=input('请输入成绩等级:')
match score:
case 'A':
print('优秀')
case 'B':
print('及格')
case 'C':
print('不及格')
case _ :
pass循环结构(for与while循环的使用场景)
1. for循环
s=0
for i in range(1,11): #range函数:产生一个[n,m)的整数序列
s+=i
print('1到10的累加和为:',s)2. for...else...语句
for循环的变种,当for循环正常循环结束后,执行else语句。
numbers = [4, 6, 8, 9, 10]
target = 7
for num in numbers:
if num == target:
print(f"找到了目标数字 {target}")
break
else: # 循环正常结束(未被 break)时执行
print(f"列表中没有找到目标数字 {target}")3. while循环
s=0
i=1 #初始化变量
while i<=100: #条件判断
s+=i #语句块
i+=i #改变变量
print('1到100的累加值为:',s)4. while...else..语句
while循环的变种,当while循环正常循环结束后,执行else语句。
attempts = 0
while attempts < 3:
user_input = input("请输入一个数字(如 123):")
if user_input.isdigit(): #str.isdigit()所有字符都是数字
print(f"有效数字:{user_input}")
break
else:
print("输入无效,请重试。")
attempts += 1
else: # 循环正常结束(未 break)时执行
print("连续3次输入无效,程序退出。")循环控制关键字(break, continue, pass)
1. break: 直接结束程序运行。
2. continue: 跳过本次循环的后续代码,并继续执行下一次循环操作。
3. pass: 只起到占位符的作用,使语法结构完整、不报错。
4. 示例:斐波那契数列实现
斐波那契数列是一个经典的数学序列,其中每个数字都是前两个数字的和,通常以 0 和 1 开始。
方法一:
def fibonacci_recursive(n):
if n <= 0:
return []
elif n == 1:
return [0]
elif n == 2:
return [0, 1]
else:
seq = fibonacci_recursive(n-1)
seq.append(seq[-1] + seq[-2])
return seq
# 示例:生成前10个斐波那契数
print(fibonacci_recursive(10)) # 输出: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]方法二:
def fibonacci_iterative(n):
if n <= 0:
return []
elif n == 1:
return [0]
seq = [0, 1]
while len(seq) < n:
seq.append(seq[-1] + seq[-2])
return seq
# 示例:生成前10个斐波那契数
print(fibonacci_iterative(10)) # 输出: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]方法有很多,可参考AI或其他文章进行思路开拓。
核心数据结构
列表(list)
1. 定义: 列表是指一系列的按特定顺序排列的元素组成。列表是Python中内置的可变序列,列表中的元素可以是任意数据类型。
2. 列表的创建方式:
直接创建:列表名=[元素1,元素2,...,元素n]
使用内置函数list()创建:列表名=list(序列)
3. 列表的删除: del 列表名
4. enumerate(枚举)函数与列表:
for index,item in enumerate(lst) #输出index和item5. 列表中的遍历操作
#for循环
for i in lst:
print(i)
#根据索引进行遍历
for i in range(0,len(lst)):
print(i,lst[i])
#用enumerate函数进行遍历
for index,item in enumerate(lst):
print(index,item)6. 列表的操作方法
7. 列表排序
#使用sort方法在原列表上进行更改
#lst.sort(key=None,reverse=False)
#key代表排序规则,reverse代表排序方式,False代表升序
lst=['banana','apple','Cat','Orange']
lst.sort()
print(lst) #输出:['Cat','Orange','apple','banana']
lst.sort(reverse=True)
print(lst) #输出:['banana','apple','Orange','Cat']
lst.sort(key=str.lower) #字符转为小写后比较
print(lst) #输出:['apple','banana','Cat','Orange']
#使用内置函数sorted()生成一个新列表
#sorted(iterable,key=None,revers=False)
#iterable表示排序的对象
new__lst=sorted(lst)
new__lst=sorted(lst,reverse=True)
new__lst=sorted(lst,key=str.lower)
#输出与sort方法的输出相同8. 列表生成式
#lst=[expression for item in range()]
#lst=[expression for item in range() if condition]
#expression是列表中数据的获取方法,item是元素个数,condition是判断条件
import random
lst=[item for item in range(1,11)]
print(lst) #输出:[1,2,3,4,5,6,7,8,9,10]
lst=[item*item for item in range(1,11)]
print(lst) #输出:[1,4,9,16,25,36,49,64,81,100]
lst=[random.randint(1,100) for _ in range(1,11)] #randint:生成随机整数
print(lst) #输出:[50,25,31,62,46,54,88,84,86,91]
lst=[i for i in range(10) if i%2==0]
print(lst) #输出:[0,2,4,6,8]9. 二维列表
#读取二维列表
for row in lst:
for item in row:
pass
#生成二维列表
lst=[[j for j in range(5)] for i in range(4)] #j代表几列,i代表几行
for j in lst: #这个二维列表有几行
for i in j: #这个二维列表每行有几列
print(i,end='\t')
print()元组(tuple)的特性与使用场景
1. 定义: 元组是Python中内置的不可变序列,用()定义元组,元素与元素间使用英文逗号进行分隔,只有一个元素时逗号也不能省略。
2. 元组的创建方式
- 用()直接创建:元组名=(元素1,元素2,...,元素n)
- 使用内置函数tuple()创建:元组名=tuple(序列)
3. 元组的删除: del 元组名
4. 元组中的索引操作:
#查找
t=(1,2,3,4,5)
print(t[0]) #输出:1
#切片
t2=t[0:5:2] #从元组t的第0位开始取,取到第4位,中间间隔为2
print(t2) #输出(1,3,5)5. 元组的遍历:
#for循环
for item in t:
print(item)
#根据索引进行遍历
for i in range(len(t)):
print(i,t[i])
#使用enumerate函数枚举遍历
for index,item in enumerate(t):
print(index,item)6. 元组的生成式
元组名=(i for i in range(a,b))
元组名=tuple(序列)
元组名=(i for i in range(a,b) if 条件)7. 依次读取__next__
t=(1,2,3)
print(t.__next__()) #输出:1
print(t.__next__()) #输出:2
print(t.__next__()) #输出:3
print(t) #输出:()8. 元组与列表的区别
字典(dict)的键值对管理与高效查找
1. 定义: 字典类型是根据一个信息去查找另一个信息的方式构成了“键值对”,他表示了索引作用的键和对应的值构成的成对关系。
2. 字典的创建方式
使用{}直接创建:d={key1:value1,key2:value2,.....}
通过映射函数创建字典,使用内置函数dict()创建:
v=zip(lst1,lst2)
d=dict(v)使用参数创造:d=dict(key1:value1,key2:value2,....)
3. 字典的删除: del 字典名
4. 字典元素的取值: d[key]或d.get(key)
5. 字典元素的遍历:
#遍历出key与value的元组
for element in d.items():
pass
#分别遍历出key和value
for key,value in d.items():
pass6. 字典的操作方法:
7. 字典生成式
d={key:value for item in range()}
d={key:value for key,value in zip(lst1,lst2)}集合(set)的去重与集合运算
1. 定义: Python中集合与数学中的集合概念一致,是一个无序的不重复元素序列,集合中只能存储不可变数据类型,在Python中用{}定义。与列表、字典一样,都是Python中的可变数据类型。
2. 集合的创建方式:
使用{}直接创建:s={element1,element2,.....,element N}
使用内置函数set()创建:s=set(可迭代对象)
3. 集合的删除: del 集合名
4. 集合的操作符:
5. 集合的操作方法:
6. 集合的遍历:
#for循环
for item in s:
pass
#使用enumerate函数
for index,item in enumerate(s)
print(index,item)7. 集合的生成式:
s={i for i in range(a,b)}
s={i for i in range(a,b) if 条件}列表、元组、字典、集合的区别
函数与模块化编程
函数定义与参数传递(位置参数、关键字参数)
1. 函数的定义: 函数是将一段实现功能的完整代码使用函数名称进行封装,通过函数名称进行调用,以此达到一次编写、多次调用的目的。
2. 自定义函数:
def 函数名称(参数列表):
函数体
[return返回值列表]3. 函数调用: 函数名称(参数列表)
4. 参数:
位置参数:是指调用时的参数个数和顺序必须与定义的参数个数相同。
关键字参数:是在函数调用时,使用‘形参名称=值’的方式进行传参,传递参数顺序可以与定义时参数的顺序不同。
默认值参数:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果改参数传值,则使用传递的值。
可变参数:
个数可变的位置参数:在参数前加一颗星(*参数名),函数调用时可接收任意个数的实际参数,并放到一个元组中。
个数可变的关键字参数:在参数前加两颗星(**参数名),函数调用时可接收任意个‘参数=值‘形式的参数,并放到一个字典中。
返回值与多返回值的元组解包
1. 返回值return: 如果函数的运行结果需要在其它函数中使用,那么这个函数就应该被定义成带返回值的函数。函数的运行结果使用return关键字进行返回, return可以出现在函数的任意一个位置用于结束函数。返回值可以是一个值或多个值,如果返回值是多个,结果是一个元组类型。
2. 元组解包的基本用法
name, age, city = get_user_info()
print(name) # 输出:Alice
print(age) # 输出:30
print(city) # 输出:Beijing
#变量数量与元组元素数量必须一致3. 元组解包的进阶用法:处理数量不匹配的情况
#使用星号(*)表达式捕获多个元素
# 示例:获取前1个元素,剩余元素用列表接收
user_info = ("Alice", 30, "Beijing", "female", "programmer")
name, *others = user_info
print(name) # 输出:Alice
print(others) # 输出:[30, 'Beijing', 'female', 'programmer']
# 示例:获取中间元素,前后用列表接收
before, city, after = user_info
print(before) # 输出:['Alice', 30]
print(city) # 输出:Beijing
print(after) # 输出:female, programmer(注意:如果after不加'*'这里after只接收最后1个元素)
#用_忽略不需要的元素
user_info = ("Alice", 30, "Beijing")
name, , city = userinfo # 忽略age
print(name) # 输出:Alice
print(city) # 输出:Beijing
#结合*和_忽略多个元素
user_info = ("Alice", 30, "Beijing", "female", "programmer")
name, *_, job = user_info # 忽略中间的30、Beijing、female
print(name) # 输出:Alice
print(job) # 输出:programmerlambda表达式的适用场景
1. lambda 表达式(匿名函数) 是 Python 中一种简洁的函数定义方式,其语法为lambda 参数: 表达式。适用于需要简单函数且仅使用一次的场景。
2. 常见场景:作为 “一次性” 函数参数
#对复杂结构(如字典、元组)排序时,用 lambda 指定排序键:
students = [("Alice", 20), ("Bob", 18), ("Charlie", 22)]
# 按年龄排序(第二个元素)
sorted_by_age = sorted(students, key=lambda x: x[1])
print(sorted_by_age) # 输出:[('Bob', 18), ('Alice', 20), ('Charlie', 22)]
#筛选可迭代对象中符合条件的元素:
numbers = [1, 2, 3, 4, 5, 6]
# 筛选偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # 输出:[2, 4, 6]
#对可迭代对象中的元素做转换:
numbers = [1, 2, 3, 4]
# 计算每个数的平方
squared = list(map(lambda x: x **2, numbers))
print(squared) # 输出:[1, 4, 9, 16]3. 常见场景: 简化函数返回值
#当函数需要返回另一个简单函数时,lambda 可以替代def定义的嵌套函数,使代码更紧凑。
def make_adder(n):
# 返回一个“加n”的函数
return lambda x: x + n
add5 = make_adder(5)
print(add5(3)) # 输出:8(3+5)
print(add5(10)) # 输出:15(10+5)4. 常见场景: 作为字典 / 列表中的 “简单逻辑” 元素
# 用字典存储不同的计算逻辑
operations = {
"add": lambda a, b: a + b,
"subtract": lambda a, b: a - b,
"multiply": lambda a, b: a * b
}
print(operations["add"](2, 3)) # 输出:5
print(operations["subtract"](5, 2)) # 输出:3
# 在字典或列表中需要嵌入简单的操作逻辑时,lambda 可以避免单独定义函数,使代码更集中。模块导入机制(import与from...import区别)
1. import 语句:
import 模块名 [as 别名],导入整个模块,使得模块中的所有公开成员(函数、类、变量等)可以通过「模块名。成员名」的方式访问。
导入的是整个模块,不会污染当前作用域(成员需通过模块名访问)
适合需要使用模块中多个成员的场景 - 可以通过 as 关键字指定别名,简化代码书写
import math # 导入 math 模块
print(math.pi) # 通过模块名访问成员
print(math.sqrt(16)) # 调用模块中的函数
# 使用别名简化访问
import math as m
print(m.pi) # 等价于 math.pi2. from…import语句:
from 模块名 import 成员名 [as 别名] 或 from 模块名 import *,直接导入模块中的指定成员(或所有成员),可以直接通过「成员名」访问,无需前缀模块名。
直接导入成员,使用时无需模块名前缀,代码更简洁
可能导致命名冲突(如果当前作用域已有同名变量 / 函数)
from...import * 会导入模块中所有公开成员(以下划线 _ 开头的私有成员除外),但可读性差,不建议在生产代码中使用
# 导入指定成员
from math import pi, sqrt
print(pi) # 直接使用成员名
print(sqrt(16))
# 为成员指定别名
from math import pi as圆周率
print(圆周率)
# 导入所有成员(不推荐)
from math import *
print(cos(0)) # 可以直接使用 math 中的所有公开成员3. import与from...import核心区别总结
文件操作与异常处理
文件读写模式(r/w/a与二进制模式)
1. 打开函数open(): 打开一个已存在的文件或传建一个新文件。open(name,mode,encoding)
2. 文本模式:
- 文本模式用于处理文本文件(如 .txt、.py 等),读写内容为字符串(str 类型),会自动处理换行符(跨平台转换)。
# 1. 读取文件(r模式)
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read() # 读取全部内容(字符串)
print(content)
# 2. 写入文件(w模式)
with open("test.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!") # 覆盖原有内容
# 3. 追加内容(a模式)
with open("test.txt", "a", encoding="utf-8") as f:
f.write("\nAppend this line.") # 新增内容到末尾文本模式操作的相关方法:
read()方法: 文件对像.read(num),多次调用时,下一次会在上一次结束处读取。num为从文件中读取数据的长度(单位:字节),如果没有num则读取所有。
readlines()方法: 按照行的方式把整个文件中的内容进行一次性读取,并返回为一个列表,其中每一行的数据为一个元素。列表名=文件对象.readlines()
for循环读取文件行: for line in open('python.txt','r'):print(line)
flush()方法: 文件对象.flush(),将内容刷新,把内容真正写入文件,close也有相同效果
3. 二进制模式:
- 二进制模式用于处理非文本文件(如图片、音频、视频、压缩包等),读写内容为字节流(bytes 类型),不处理换行符,需显式指定 b 标志。
# 1. 读取图片(二进制文件)
with open("image.png", "rb") as f:
data = f.read() # 读取字节流(bytes类型)
# 2. 复制图片(二进制读写)
with open("image.png", "rb") as src, open("copy.png", "wb") as dst:
dst.write(src.read()) # 直接写入字节流4. 文本模式与二进制模式的区别:
5. close()方法: 将内容刷新并关闭文件对象
with上下文管理器的资源自动释放
1. with语句能自动处理资源的分配与释放,避免因忘记关闭资源而导致的内存泄漏或文件损坏等问题。当处理文件、网络连接、数据库连接等有限资源时,with 语句的核心优势是无论代码块正常执行还是发生异常,都会确保资源被正确释放。
# 风险:若中间代码报错,可能导致文件未关闭
f = open("test.txt", "r")
content = f.read()
f.close() # 必须手动调用,否则资源可能泄露
# 安全:无论是否发生异常,文件都会自动关闭
with open("test.txt", "r") as f:
content = f.read()
# 离开 with 代码块后,f 已自动关闭,无需手动操作2. with 语句的实现依赖于 上下文管理器协议,即对象必须实现两个特殊方法:
enter():进入 with 代码块时调用,返回需要管理的资源(如文件对象)。
exit():离开 with 代码块时调用(无论正常退出还是异常退出),负责释放资源。
class MyFile:
def init(self, filename, mode):
self.filename = filename
self.mode = mode
def enter(self):
self.file = open(self.filename, self.mode)
return self.file # 返回资源给 as 后的变量
def exit(self, exc_type, exc_val, exc_tb):
self.file.close() # 自动释放资源
# 处理异常(可选)
if exc_type:
print(f"发生异常:{exc_val}")
return False # 不抑制异常,让其继续传播
# 使用自定义上下文管理器
with MyFile("test.txt", "w") as f:
f.write("Hello, Context Manager!")3. with语句的使用场景:
文件操作
with open("data.csv", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())数据库连接
import sqlite3
with sqlite3.connect("mydb.db") as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
# 离开代码块后,连接自动关闭网络连接
import socket
with socket.socket() as s:
s.connect(("example.com", 80))
s.send(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
# 套接字自动关闭锁机制
import threading
lock = threading.Lock()
with lock:
# 临界区代码(自动获取和释放锁)
pass常见异常类型(IOError, ValueError等)
1. 基础异常类
Exception:所有非系统退出类异常的基类,几乎所有自定义异常都继承自它。
BaseException:所有异常的顶层基类,包括 Exception 和系统退出类异常(如 SystemExit)。
2. 常见具体异常类型
3. 异常处理示例
使用 try...except 捕获并处理异常:
try:
# 可能触发异常的代码
num = int(input("请输入数字:"))
result = 10 / num
print(f"结果:{result}")
except ValueError:
print("错误:输入不是有效的数字")
except ZeroDivisionError:
print("错误:除数不能为零")
except Exception as e:
# 捕获其他未预料的异常
print(f"发生未知错误:{e}")4. 注意
异常类型反映了错误的具体原因,针对性捕获能让代码更健壮。
避免使用 except Exception 捕获所有异常(可能掩盖真正的问题),应优先捕获具体异常。
调试时,异常的堆栈信息(traceback)会显示错误类型和位置,是排查问题的关键。
try-except-finally的完整处理流程
1. 基本结构
try:
# 可能发生异常的代码块(核心逻辑)
risky_operation()
except 异常类型1 [as 变量名]:
# 若发生「异常类型1」,执行此处代码(处理异常)
handle_error_type1()
except (异常类型2, 异常类型3) [as 变量名]:
# 若发生「异常类型2」或「异常类型3」,执行此处代码
handle_error_type2_or_3()
else:
# 若 try 块无异常,执行此处代码(可选)
no_error_operation()
finally:
# 无论是否发生异常,都会执行此处代码(释放资源等)
must_execute_operation()2. 执行流程详解
1. try 块优先执行:
程序首先执行 try 中的代码,这是可能发生异常的核心逻辑。
2. 若 try`块发生异常:
立即中断 try块执行,跳转到对应的 except块匹配异常类型。
若找到匹配的 except 块,执行其中的异常处理代码。
若未找到匹配的 except 块,异常会向上传播(可能导致程序终止)。
无论是否匹配到 except,最终都会执行 finally 块。
3. 若 try 块无异常:
执行完 try 块后,跳过所有 except 块。
若有 else 块,执行 else 中的代码(else 是无异常时的附加逻辑)。
最后执行 finally 块。
4. finally 块的必然性:
无论 try 块是否异常、except 块是否匹配、甚至 return/break 语句,finally 块一定会执行,常用于释放资源(如关闭文件、断开连接)。
3. 实例演示
def read_file_safely(filename):
file = None # 初始化变量,避免未定义错误
try:
file = open(filename, "r", encoding="utf-8")
content = file.read()
print("文件内容:", content[:100]) # 打印前100字符
return "读取成功" # 无异常时返回
except FileNotFoundError:
print(f"错误:文件 '{filename}' 不存在")
return "读取失败" # 异常时返回
except UnicodeDecodeError as e:
print(f"错误:文件编码异常 - {e}")
return "读取失败"
else:
print("额外操作:文件读取无异常,记录日志") # 仅无异常时执行
finally:
# 无论是否异常,确保文件关闭
if file:
file.close()
print("资源释放:文件已关闭")
# 测试:文件存在且正常
read_file_safely("test.txt")
# 测试:文件不存在
read_file_safely("nonexist.txt")4. 关键特性
except 多分支:可按异常类型精准处理,避免一刀切捕获所有异常。
else 块作用:分离「核心逻辑」和「无异常时的附加逻辑」,使代码更清晰。
finally不可替代:即使在 try 或 except 中使用 return,finally仍会执行(如下):
def demo():
try:
return 1 # 尝试返回
finally:
print("finally 执行了") # 仍会执行
demo() # 输出:finally 执行了,返回值 15. 使用场景
try:包裹可能出错的核心代码(如文件操作、网络请求)。
except:针对性处理可预见的异常(如文件不存在、网络超时)。
else:处理无异常时的附加逻辑(如日志记录、结果校验)。
finally:必做的收尾工作(如关闭文件/连接、释放锁、清理临时文件)。
面向对象编程基础
类与对象的概念解析
1. 类(Class): 类是对一类事物共同特征和行为的抽象描述,它不特指某个具体的事物,而是定义了这类事物"是什么"(属性)和"能做什么"(方法)。
属性(Attribute):类中定义的变量,用于描述事物的特征。例如"人"类的属性可以是姓名、年龄、性别等。
方法(Method):类中定义的函数,用于描述事物的行为。例如"人"类的方法可以是走路、说话、吃饭等。
2. 对象(Object): 对象是类的具体实例,是根据类创建的具体个体。它具有类中定义的属性和方法,并且属性有具体的值。一个类可以创建多个对象,每个对象的属性值可以不同,但都遵循类定义的结构。
3. 面向对象的核心意义
封装性: 类将属性和方法封装在一起,对外隐藏实现细节,只暴露必要的接口。
复用性: 通过类可以快速创建多个对象,避免重复代码。
扩展性: 基于已有类可以创建新类(继承),实现功能的扩展。
4. 代码示例(Python)
# 定义一个"人"类(模板)
class Person:
# 属性(特征)
def init(self, name, age):
self.name = name # 姓名
self.age = age # 年龄
# 方法(行为)
def speak(self):
print(f"我叫{self.name},今年{self.age}岁")
# 创建对象(具体实例)
person1 = Person("张三", 20) # 第一个对象
person2 = Person("李四", 30) # 第二个对象
# 调用对象的方法
person1.speak() # 输出:我叫张三,今年20岁
person2.speak() # 输出:我叫李四,今年30岁
#在这个例子中,`Person`是类,`person1`和`person2`是根据该类创建的两个不同对象,它们都有`name`、`age`属性和`speak()`方法,但属性值不同。构造方法(init)与实例属性
1. 构造方法(\__init__): 构造方法是类中一个特殊的方法,用于在创建对象时初始化对象的属性。
特点:
当通过类创建对象时,\__init__ 会被自动调用。
第一个参数必须是self,代表当前正在创建的对象本身。
可以定义额外参数,用于为对象的属性赋值。
作用:
为新创建的对象设置初始状态(属性值)。
执行对象创建时必需的初始化操作(如打开文件、连接数据库等)。
2. 实例属性: 实例属性是属于具体对象的属性,每个对象的实例属性可以有不同的值。它们通常在构造方法中通过 self.属性名 定义。
特点:
每个对象的实例属性独立存储,修改一个对象的属性不会影响其他对象。
必须通过对象(或 self)访问,如 p.name 或 self.name。
3. 构造方法与实例属性的关系: 构造方法是定义和初始化实例属性的主要场所。通过 __init__ 方法的参数,可以在创建对象时为实例属性赋值,使每个对象一创建就具备具体的属性值。
class Person:
# 构造方法:初始化实例属性
def init(self, name, age): # name和age是外部传入的参数
self.name = name # 定义并初始化实例属性name
self.age = age # 定义并初始化实例属性age
def introduce(self):
# 通过self访问实例属性
print(f"我叫{self.name},今年{self.age}岁")
# 创建对象时,自动调用__init__,传入参数初始化属性
p1 = Person("张三", 20)
p2 = Person("李四", 30)
# 访问实例属性
print(p1.name) # 输出:张三
print(p2.age) # 输出:30
# 调用方法(方法内部使用了实例属性)
p1.introduce() # 输出:我叫张三,今年20岁4. 关键点说明
self 的作用:self 是构造方法(及所有实例方法)的第一个参数,代表当前对象。通过 self.属性名 定义的属性,会成为该对象的实例属性。
默认参数:构造方法可以使用默认参数,使创建对象时某些属性可选:
class Person:
def init(self, name, age=18): # age默认值为18
self.name = name
self.age = age
p = Person("王五") # 不传入age,使用默认值18
print(p.age) # 输出:18实例属性的动态添加:除了在 __init__ 中定义,也可以在对象创建后动态添加实例属性(但不推荐,会导致代码混乱):
p1 = Person("张三", 20)
p1.gender = "男" # 动态添加gender属性继承与方法重写(super()函数使用)
1. 继承(Inheritance): 继承是指 一个类(子类)可以继承另一个类(父类)的属性和方法,并可以在此基础上添加新的属性或方法,或修改父类的方法。
作用:
代码复用:无需重复编写父类已有的代码。
功能扩展:在父类基础上添加新功能。
多态实现:为不同子类的同名方法提供统一调用接口。
# 父类(基类)
class Parent:
def parent_method(self):
print("这是父类的方法")
# 子类(派生类),继承自Parent
class Child(Parent):
def child_method(self):
print("这是子类的方法")
# 子类对象可以调用父类和自身的方法
c = Child()
c.parent_method() # 输出:这是父类的方法(继承自父类)
c.child_method() # 输出:这是子类的方法(自身方法)2. 方法重写(Override): 子类的"个性化改造"
当子类需要对父类的方法进行**修改或扩展**时,可以定义与父类同名的方法,这称为方法重写。
场景:
父类方法的逻辑不满足子类需求。
需要在父类方法基础上添加新逻辑。
class Animal:
def speak(self):
print("动物发出声音")
# 子类Dog重写speak方法
class Dog(Animal):
def speak(self): # 与父类方法同名
print("汪汪汪")
# 子类Cat重写speak方法
class Cat(Animal):
def speak(self): # 与父类方法同名
print("喵喵喵")
dog = Dog()
dog.speak() # 输出:汪汪汪(调用重写后的方法)
cat = Cat()
cat.speak() # 输出:喵喵喵(调用重写后的方法)3. super()函数: super() 用于在子类中**调用父类的方法或属性**,尤其在方法重写时,可以保留父类的逻辑并添加子类特有的逻辑。
常见用法:
1. 在子类构造方法中调用父类构造方法
确保父类的属性被正确初始化。
2. 在重写的方法中调用父类的同名方法
复用父类逻辑,再添加子类特有的逻辑。
#在构造方法中使用super()
class Person:
def init(self, name, age):
self.name = name
self.age = age
class Student(Person):
def init(self, name, age, school):
# 调用父类的__init__方法,初始化name和age
super().__init__(name, age)
# 子类新增属性
self.school = school
def introduce(self):
print(f"我叫{self.name},{self.age}岁,在{self.school}上学")
s = Student("张三", 18, "北京大学")
s.introduce() # 输出:我叫张三,18岁,在北京大学上学
#在重写方法中使用super()
class Animal:
def move(self):
print("动物在移动")
class Bird(Animal):
def move(self):
# 先调用父类的move方法
super().move()
# 再添加子类特有的逻辑
print("鸟在飞翔")
bird = Bird()
bird.move()
# 输出:
# 动物在移动
# 鸟在飞翔4. 关键点说明
super()的本质:super() 并非直接调用"父类",而是调用**继承链中的下一个类**(适用于多继承场景)。
参数传递:在super()调用中,无需手动传递self参数,Python会自动处理。
多继承中的super(): 在多继承(如class C(A, B))中,super() 会按照**MRO(方法解析顺序)** 调用下一个类的方法,避免方法调用冲突。
魔术方法(如__str__, len)的实用案例
1. __str__():自定义对象的字符串表示
__str__() 用于定义对象被print()或str()转换时的字符串格式,让对象的输出更具可读性。
#定义一个Book类,打印时显示书籍的基本信息
class Book:
def init(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
# 自定义字符串表示
def str(self):
return f"《{self.title}》- 作者:{self.author}({self.pages}页)"
book = Book("Python编程", "张三", 300)
print(book) # 自动调用__str__(),输出:《Python编程》- 作者:张三(300页)
print(str(book)) # 同样调用__str__(),输出同上2. __len__():让对象支持len()函数
__len__() 用于定义当调用len(obj)时的返回值,通常用于表示对象的"长度"或"数量"。
#定义一个ShoppingCart类,用len()获取购物车中商品数量
class ShoppingCart:
def init(self):
self.items = [] # 存储商品的列表
def add_item(self, item):
self.items.append(item)
# 定义len()的返回值为商品数量
def len(self):
return len(self.items)
cart = ShoppingCart()
cart.add_item("苹果")
cart.add_item("香蕉")
print(len(cart)) # 自动调用__len__(),输出:23. __getitem__()和__setitem__():让对象支持索引操作
这两个方法用于使对象可以像列表或字典一样通过[ ]进行取值和赋值。
#定义一个StudentList类,支持用索引访问学生
class StudentList:
def init(self):
self.students = []
# 支持obj[index]取值
def getitem(self, index):
return self.students[index]
# 支持obj[index] = value赋值
def setitem(self, index, value):
self.students[index] = value
students = StudentList()
students.students = ["张三", "李四", "王五"]
print(students[0]) # 调用__getitem__(),输出:张三
students[1] = "赵六" # 调用__setitem__()
print(students[1]) # 输出:赵六4. __add__():自定义对象的加法运算
__add__() 用于定义两个对象相加(+)时的逻辑。
#定义一个Vector类,实现向量的加法
class Vector:
def init(self, x, y):
self.x = x
self.y = y
# 自定义加法:两个向量的x和y分别相加
def add(self, other):
return Vector(self.x + other.x, self.y + other.y)
def str(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # 自动调用__add__()
print(v3) # 输出:Vector(6, 8)5. __bool__():自定义对象的布尔值判断
__bool__() 用于定义对象在布尔判断(如 if obj:)时的返回值,默认情况下所有对象都为True。
#定义一个Account类,余额为0时视为False
class Account:
def init(self, balance=0):
self.balance = balance
# 余额为0时返回False,否则返回True
def bool(self):
return self.balance > 0
acc1 = Account(100)
acc2 = Account(0)
if acc1:
print("账户1有余额") # 会执行
if acc2:
print("账户2有余额") # 不会执行6. 魔术方法的核心价值
增强可读性:如__str__()让对象的输出更直观。
模拟内置类型:通过__len__()、__getitem__()等让自定义类像列表、字典一样使用。
简化逻辑:将特定操作(如加法、判断)封装在魔术方法中,使代码更简洁。
标准库常用模块
os和sys模块的系统交互
1. os模块: 主要用于与操作系统进行交互,提供了访问文件系统、环境变量、进程管理等功能,它更偏向于操作系统层面的操作。
#os模块常用功能
import os
# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前工作目录: {current_dir}")
# 列出目录中的文件和文件夹
files = os.listdir(current_dir)
print(f"目录内容: {files}")
# 创建目录
new_dir = "test_dir"
os.mkdir(new_dir)
# 重命名文件/目录
os.rename(new_dir, "new_test_dir")
# 删除目录
os.rmdir("new_test_dir")
# 获取环境变量
path_var = os.environ.get("PATH")
print(f"PATH环境变量: {path_var}")
# 执行系统命令
os.system("echo Hello from system command!")3. sys模块: 主要用于与Python解释器本身进行交互,提供了与解释器相关的配置和操作,比如命令行参数、解释器版本信息、标准输入输出等。
#sys模块常用功能
import sys
# 获取命令行参数
print(f"命令行参数: {sys.argv}")
# 获取Python解释器版本信息
print(f"Python版本: {sys.version}")
# 获取系统平台
print(f"系统平台: {sys.platform}")
# 标准输出重定向
print("这是标准输出")
sys.stdout.write("这也是标准输出\n")
# 退出程序
sys.exit(0) # 0表示正常退出,非0表示异常退出
# 获取模块搜索路径
print(f"模块搜索路径: {sys.path}")datetime模块的时间处理
1. datetime 模块: datetime 模块是处理日期和时间的核心工具,提供了简洁且功能丰富的类来操作时间,包括日期计算、格式转换、时区处理等。
2. datetime的核心类:
date: 处理年、月、日(日期)
time: 处理时、分、秒、微秒(时间)
datetime: 同时处理日期和时间(最常用)
timedelta: 表示时间间隔(用于日期加减)
tzinfo/timezone: 处理时区(Python 3.2+ 新增 timezone 简化时区操作)
3. 常用功能示例:
#获取当前时间
from datetime import datetime, date, time
# 获取当前日期时间(datetime对象)
now = datetime.now()
print("当前时间:", now) # 输出:2023-10-15 14:30:45.123456
# 获取当前日期(date对象)
today = date.today()
print("当前日期:", today) # 输出:2023-10-15
# 单独获取年、月、日、时、分、秒
print("年:", now.year) # 2023
print("月:", now.month) # 10
print("日:", now.day) # 15
print("时:", now.hour) # 14
print("分:", now.minute) # 30
print("秒:", now.second) # 45#创建指定时间
from datetime import datetime, date, time
# 创建指定日期时间(datetime)
dt = datetime(2023, 10, 1, 8, 30, 0)
print("指定时间:", dt) # 2023-10-01 08:30:00
# 创建指定日期(date)
d = date(2023, 12, 25)
print("指定日期:", d) # 2023-12-25
# 创建指定时间(time)
t = time(18, 45, 30)
print("指定时间:", t) # 18:45:30#时间格式转换(字符串与datetime互转)
#strftime():将 datetime 转为字符串(格式化输出)
#strptime():将字符串转为 datetime(解析输入)
from datetime import datetime
# datetime -> 字符串(格式化)
now = datetime.now()
str1 = now.strftime("%Y-%m-%d %H:%M:%S") # 年-月-日 时:分:秒
str2 = now.strftime("%Y年%m月%d日 %H时%M分") # 中文格式
print("格式化后:", str1) # 2023-10-15 14:30:45
print("中文格式:", str2) # 2023年10月15日 14时30分
# 字符串 -> datetime(解析)
str_time = "2023-10-01 08:30:00"
dt = datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
print("解析后的时间:", dt) # 2023-10-01 08:30:00
"""
常用格式化符号
%Y:四位数年份(如 2023)
%m:两位数月份(01-12)
%d:两位数日期(01-31)
%H:24小时制小时(00-23)
%M:分钟(00-59)
%S:秒(00-59)
"""# 时间间隔计算(timedelta)
#timedelta 用于表示时间差,可直接与 datetime 进行加减运算。
from datetime import datetime, timedelta
now = datetime.now()
# 计算3天后的时间
future = now + timedelta(days=3)
print("3天后:", future) # 2023-10-18 14:30:45.123456
# 计算1小时30分钟前的时间
past = now - timedelta(hours=1, minutes=30)
print("1小时30分钟前:", past) # 2023-10-15 13:00:45.123456
# 计算两个时间的差
delta = future - past
print("时间差(天):", delta.days) # 3
print("时间差(总秒数):", delta.total_seconds()) # 270000.0(3天×86400秒)#时区处理
#使用 pytz 库(需安装:pip install pytz)或 Python 3.9+ 的 zoneinfo 处理时区。
from datetime import datetime
import pytz # 第三方时区库
# 获取纽约时间(UTC-4/UTC-5,随季节变化)
ny_tz = pytz.timezone('America/New_York')
ny_time = datetime.now(ny_tz)
print("纽约时间:", ny_time.strftime("%Y-%m-%d %H:%M:%S"))
# 获取北京时区(UTC+8)
bj_tz = pytz.timezone('Asia/Shanghai')
bj_time = datetime.now(bj_tz)
print("北京时间:", bj_time.strftime("%Y-%m-%d %H:%M:%S"))json模块的数据序列化
1. json模块: 提供了对 JSON 数据格式的序列化(将 Python 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换为 Python 对象)功能,是处理 JSON 数据的核心工具。
2. json模块中的核心函数
json.dumps():将 Python 对象序列化为 JSON 字符串
json.dump():将 Python 对象序列化为 JSON 字符串并写入文件
json.loads():将 JSON 字符串反序列化为 Python 对象
json.load():从文件中读取 JSON 字符串并反序列化为 Python 对象
3. Python 与 JSON 类型对应关系: 序列化时,Python 类型会被转换为对应的 JSON 类型
4. 序列化(Python → JSON)
import json
# 定义一个 Python 字典(可序列化的对象)
data = {
"name": "Alice",
"age": 30,
"is_student": False,
"hobbies": ["reading", "hiking"],
"address": {
"city": "New York",
"zipcode": "10001"
},
"score": None
}
# 使用 dumps() 转为 JSON 字符串
json_str = json.dumps(data)
print("JSON 字符串:", json_str)
# 输出:{"name": "Alice", "age": 30, "is_student": false, "hobbies": ["reading", "hiking"], "address": {"city": "New York", "zipcode": "10001"}, "score": null}
# 格式化输出(更易读)
pretty_json = json.dumps(data, indent=4, ensure_ascii=False)
print("格式化 JSON:")
print(pretty_json)
"""
dumps() 常用参数:
indent:指定缩进空格数,美化输出
ensure_ascii:默认 True(非 ASCII 字符转义),设为 False 可保留中文等字符
sort_keys:设为 True 可按 key 排序
"""5. 反序列化(JSON → Python)
import json
# JSON 字符串
json_str = '''
{
"name": "Bob",
"age": 25,
"is_student": true,
"hobbies": ["coding", "gaming"],
"address": {
"city": "London",
"zipcode": "SW1A 1AA"
},
"score": null
}
'''
# 使用 loads() 转为 Python 字典
python_data = json.loads(json_str)
print("Python 对象类型:", type(python_data)) # <class 'dict'>
print("姓名:", python_data["name"]) # Bob
print("爱好:", python_data["hobbies"][0]) # coding6. 与文件交互
import json
data = {"name": "Charlie", "age": 35}
# 序列化并写入文件(dump())
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
# 从文件读取并反序列化(load())
with open("data.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print("从文件读取的数据:", loaded_data) # {'name': 'Charlie', 'age': 35}处理复杂对象(自定义序列化)
默认情况下,json 模块只能序列化标准 Python 类型。如果需要序列化自定义类对象,需定义 default 函数 或实现类的 __dict__ 方法。
示例:序列化自定义类
import json
class Person:
def init(self, name, age):
self.name = name
self.age = age
# 自定义序列化函数
def person_serializer(obj):
if isinstance(obj, Person):
return {"name": obj.name, "age": obj.age, "type": "Person"}
raise TypeError(f"无法序列化 {type(obj)} 类型的对象")
# 创建自定义对象
person = Person("David", 40)
# 使用 default 参数指定序列化函数
json_str = json.dumps(person, default=person_serializer, indent=4)
print(json_str)
# 输出:
# {
# "name": "David",
# "age": 40,
# "type": "Person"
# }random模块的随机数生成
1. random 模块: random 模块提供了丰富的随机数生成功能,可用于生成随机整数、浮点数、随机选择序列元素等场景。用户可以根据根据场景选择合适的函数,例如抽奖可用 choice() 或 sample(),洗牌可用 shuffle(),数值模拟可用 gauss() 等。
2. 生成随机浮点数:
random.random(): 生成 [0.0, 1.0) 之间的随机浮点数
random.uniform(a, b):生成 [a, b] 或 [b, a] 之间的随机浮点数(取决于 a 和 b 的大小)
import random
# 生成 [0.0, 1.0) 之间的随机浮点数
print(random.random()) # 示例:0.783421569
# 生成 [1.5, 3.5] 之间的随机浮点数
print(random.uniform(1.5, 3.5)) # 示例:2.89123453. 生成随机整数:
random.randint(a, b): 生成 [a, b] 之间的整数(包含 a 和 b)
random.randrange(start, stop[, step]): 从指定范围中按步长随机选择整数(类似 range() 用法)
import random
# 生成 1-10 之间的随机整数(包含1和10)
print(random.randint(1, 10)) # 示例:7
# 从 0-20 中随机选择偶数(步长为2)
print(random.randrange(0, 21, 2)) # 示例:144. 随机选择元素:
random.choice(seq): 从非空序列中随机选择一个元素
random.choices(seq, weights=None, k=1): 从序列中随机选择 k 个元素(可带权重,允许重复)
import random
fruits = ["苹果", "香蕉", "橙子", "草莓"]
# 随机选择一个水果
print(random.choice(fruits)) # 示例:香蕉
# 带权重随机选择(草莓被选中概率更高)
print(random.choices(fruits, weights=[1, 1, 1, 3], k=2)) # 示例:['草莓', '橙子']5. 打乱序列顺序:
random.shuffle(seq): 原地打乱序列(修改原序列,无返回值)
import random
nums = [1, 2, 3, 4, 5]
random.shuffle(nums) # 原地打乱
print(nums) # 示例:[3, 1, 5, 2, 4]6. 随机抽样(无重复):
random.sample(seq, k): 从序列中随机选择 k 个不重复的元素
import random
cards = ["红桃A", "黑桃K", "方块Q", "梅花J", "大王"]
# 随机抽取2张不重复的牌
print(random.sample(cards, 2)) # 示例:['黑桃K', '梅花J']7. 随机种子(确保结果可复现):
random.seed(a=None): 设置随机数种子,相同种子会生成相同的随机序列(用于调试或复现结果)
import random
# 设置种子
random.seed(10)
print(random.randint(1, 100)) # 结果固定为 73
# 再次设置相同种子,结果相同
random.seed(10)
print(random.randint(1, 100)) # 仍然输出 738. 生成高斯分布随机数:
random.gauss(mu, sigma): 生成符合高斯分布(正态分布)的随机数,mu 是均值,sigma 是标准差
import random
# 生成均值为0,标准差为1的高斯随机数
print(random.gauss(0, 1)) # 示例:0.283456注意事项
random 模块生成的是**伪随机数**(基于种子的确定性算法),不适用于加密场景
加密级随机数需使用 secrets 模块(Python 3.6+)
多线程环境下,random 模块可能存在线程安全问题,可使用 random.getstate() 和 random.setstate() 保存/恢复状态
结束语
本篇内容到此就结束了,如果你已经很好地理解了本篇的内容,那么恭喜你,你可以自豪的说:“我学过Python了”。是不是有点失望,我学了这么久怎么才是学过,我明明已经会了。回忆一下开头,Python这门语言包含了丰富的标准库,这些标准库构成了Python无所不能的美名。单单学完本篇,你只是拿到了前往各种库的钥匙,所以前方的区域已经对你开放,继续探索吧旅行者\^_^