参考:
文章目录
- 参考:
- 第1章:Pyhton解释器和Pycharm
- 第2章:Python编程基础
- 第3章:Python基础知识
- 第4章:程序组织结构
- 第5章:Python容器
- 第6章:正则表达式
- 第7章:异常处理
- 第8章:函数
- 第九章:面向对象编程
- 第10章:包与模块
- 第11章:文件操作
- 第12章:程序与进程
第1章:Pyhton解释器和Pycharm
1.Python解释器下载
下载地址:Python官网
2.Python解释器的安装
默认安装
下载好.exe文件,双击打开,点击Install Now
自定义安装
点击Customize installation
相关包,全部勾选,然后next
勾选图示选项,可以自定义安装Python解释器路径,建议默认
然后点击Install
安装验证
安装好后,打开命令提示符
终端下输入python --version ,出现Python版本,说明安装成功。
3.Python解释器的卸载
第一步,打开控制面板
第二步,点击卸载程序
第三步,搜索Python
第四步,右键单击,卸载即可
4.Pycharm的下载
- Pycharm简介:
- PyCharm 是 Python 开发者的生产力神器:社区版适合学习/基础开发,专业版满足企业级需求
- 核心特点:
- 智能编码:自动补全、实时查错、代码重构、类型提示支持。
- 强大调试图形化调试器 + 单元测试集成(支持 pytest/unittest)。
- 高效工具版本控制(Git)、终端、数据库工具、科学计算。
- 框架支持深度兼容 Django, Flask, FastAPI 等。
下载地址:Pycarm官网
5.Pycharm的安装
第一步,双击安装程序
点击安装,开始安装。
6.Pycharm的使用
第一步
第二步,点击新建项目
第三步
第四步,创建Python文件
第五步,编写Python程序并运行
终端出现Hello World说明运行成功
接下来就可以在这里编写Python程序了
第2章:Python编程基础
1.程序设计语言
- 程序设计语言一种用于编写计算机指令的标准化语言,是人与机器沟通的桥梁。
- 程序设计语言分为,机器语言,汇编语言,高级语言,逐级远离底层,Python是高级语言,
2.编译和解释
以下是编译和解释的最简区别说明:
核心区别
编译 (Compile) | 解释 (Interpret) | |
---|---|---|
过程 | 一次性翻译整个程序 | 逐行翻译并执行 |
产物 | 生成独立可执行文件 | 不生成独立文件 |
速度 | 执行快(直接跑机器码) | 执行慢(边翻译边运行) |
修改 | 改代码需重新编译 | 改代码可直接运行 |
跨平台 | 不同系统需重新编译 | 有解释器就能运行 |
-
编译:
像把一本英文书翻译成中文出版(一次性完成),读者直接读中文版(执行快)。
代表语言:C、C++、Go -
解释:
像同声传译,演讲者说一句英文(代码),翻译实时翻一句中文(执行),观众同步听。
代表语言:Python、JavaScript、PHP
3.Python简介
Python简介
- Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言
- Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
- Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
- Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码。
- Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
- Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。
Python特点
- 1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。
- 2.易于阅读:Python代码定义的更清晰。
- 3.易于维护:Python的成功在于它的源代码是相当容易维护的。
- 4.一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。
- 5.互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。
- 6.可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。
- 7.可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。
- 8.数据库:Python提供所有主要的商业数据库的接口。
- 9.GUI编程:Python支持GUI可以创建和移植到许多系统调用。
- 10.可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"的能力。
Python应用
- Youtube - 视频社交网站
- Reddit - 社交分享网站
- Dropbox - 文件分享服务
- 豆瓣网 - 图书、唱片、电影等文化产品的资料数据库网站
- 知乎 - 一个问答网站
- 果壳 - 一个泛科技主题网站
- Bottle - Python微Web框架
- EVE - 网络游戏EVE大量使用Python进行开发
- Blender - 使用Python作为建模工具与GUI语言的开源3D绘图软件
- Inkscape - 一个开源的SVG矢量图形编辑器。
Python开发环境
刚刚安装好的Python解释器,自带IDLE(Integrated Development and Learning Environment(集成开发与学习环境))
Python开发工具
这里使用的开发工具就是刚刚安装的Pycharm
4.IPO程序编写方法
IPO(Input,Process,Output),(输入,处理,输出)
5.基本的的输出函数print
语法结构
print(输出内容)
print函数的完整语法格式
print(value=,...,sep=' ',end='\n',file=None)
演示1
- 代码
a = 100 # 变量a 值为100
b = 50 # 变量b 值为50
print(90)
print(a) # 输出的是变量a的值
print(a*b) # 输出a*b的计算结果 5000
print("北京欢迎你")
print('北京欢迎你')
print("""北京欢迎你""")
print('''北京欢迎你''')
- 输出
90
100
5000
北京欢迎你
北京欢迎你
北京欢迎你
北京欢迎你
演示2
- 代码
a = 100
b = 50
print(a,b,"你好,Hello")
- 输出
100 50 你好,Hello
演示3,输出ASCII对应的字符
- 代码
print('b') # 直接输出b
print(chr(98)) # 也输出b,适应chr()先将98转换为ASCII表中的字符‘b’
print('C')
print(chr(67))
print(8)
print(chr(56))
print('[')
print(chr(91))
- 输出
b
b
C
C
8
8
[
[
演示4:使用print()输出中文Unicode码
- 代码
print(ord('北'))
print(ord('京'))
print(chr(21271),chr(20140))
- 输出
21271
20140
北 京
演示5;使用print()讲内容输出到文件
- 代码
fp = open("note.txt",'w',encoding="utf-8") # 打开note.txt文件 w --> write 以写的方式打开文件
print("北京欢迎你",file=fp) # 将“北京欢迎你” 写入note.txt文件
fp.close() # 关闭文件
- 输出
详解print(value=,...,sep=' ',end='\n',file=None)
若没有写参数,则默认
sep = ” “ 表示每个值之间用空格隔开
end = “\n” 表示每个print()输出操作以"\n"即换行符结束,对比看演示1和演示2
演示6:修改分隔符和结束符输出 - 代码
print("北京",end="-->")
print("欢迎您")
print("北京","欢饮您",sep="-->")
- 输出
北京-->欢迎您
北京-->欢饮您
6.基本输入函数input
演示1:基本的输入
- 代码
name = input("enter your name:")
print("your name is",name)
- 输出
enter your name:Shun // 这里Shun是自己在终端输入的
your name is Shun
演示2:实现整型的输入
- 代码
number = input("请输入你的幸运数字:")
print("你的幸运数字是"+number) # + 用于链接字符串
num = int(number)
# print("你的幸运数字是"+ num) 转成数字了就无法用 + 实现字符串的拼接了
# 所以可以这样输出
print("你的幸运数字是",num,sep="")
- 输出
请输入你的幸运数字:8 // 第一个8是自己在终端输入的
你的幸运数字是8
你的幸运数字是8
7.Python注释
注释可以提升代码的可读性,不会被Python解释器解释。
单行注释:“#” + 注释内容
多行注释:‘’’ 多行内容’‘’ 或 “”“多行内容”“”
示例
- 代码
# 要求从键盘输入出生年份,要求是4位年份,例如1990 这是单行注释
year = input("请从键盘输入出生年份,要求是4位年份:")
'''
这是
多行
注释
'''
这是
多行 # 这里内容没被注释起来,不符合Python程序规范就会报错
注释
8.Python代码缩进
需要缩进的情况
-
复合语句后
所有以冒号:
结尾的语句,下一行必须缩进:# 函数定义 def func(): # 有冒号 print("缩进") # 必须缩进 # 条件语句 if x > 0: # 有冒号 print("正数") # 必须缩进 # 循环 for i in range(5): # 有冒号 print(i) # 必须缩进 # 上下文管理器 with open("file.txt") as f: # 有冒号 data = f.read() # 必须缩进
-
代码块延续
同一代码块内的所有语句必须保持相同缩进:if condition: action1() # 缩进 action2() # 缩进(与上一行相同) if nested: # 缩进(相同层级) nested_action() # 更深一级缩进
不需要缩进的情况
-
顶级代码(模块层级)
所有不在函数/类/流程控制中的代码:import sys # 无缩进 x = 10 # 无缩进 def func(): # 无缩进(函数定义开始) ... # 这里才需要缩进 print("结束") # 无缩进
-
代码块结束后
当减少缩进回到上级层级时:for i in range(3): print(i) # 需要缩进(循环体内) print("循环结束") # 无缩进(已退出循环块)
-
跨行表达式的延续行
使用括号/中括号/大括号时,续行可自由缩进(非语法强制):# 不需要严格缩进(但建议对齐) result = (value1 + value2 - # 可缩进也可不缩进 value3) # 这也是合法的(但不推荐) names = [ "Alice", "Bob", "Charlie" ]
经典错误示例
# 错误1:忘记在冒号后缩进
if True:
print("会报错") # IndentationError
# 错误2:意外缩进
x = 10 # 顶级代码不能缩进(IndentationError)
# 错误3:缩进不一致
def func():
print("A") # 4空格
print("B") # 2空格(IndentationError)
第3章:Python基础知识
保留字和标识符
1.保留字
保留字是 Python 语言中具有特殊含义和功能的单词,不能用作标识符名称。
1.1.Python所有保留字
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
1.2.保留字分类及功能
类别 | 保留字 | 主要功能 |
---|---|---|
逻辑值 | True , False , None | 表示布尔值和空值 |
条件控制 | if , elif , else | 条件分支控制 |
循环控制 | for , while , break , continue | 循环控制流程 |
异常处理 | try , except , finally , raise | 异常捕获和处理 |
函数定义 | def , return , lambda | 函数和匿名函数定义 |
类定义 | class | 类定义 |
导入模块 | import , from , as | 模块导入和别名 |
作用域 | global , nonlocal | 变量作用域声明 |
逻辑运算 | and , or , not , is | 逻辑运算和身份判断 |
成员判断 | in | 成员关系判断 |
上下文管理 | with | 上下文管理器(资源自动管理) |
断言 | assert | 调试断言 |
删除 | del | 删除对象引用 |
异步编程 | async , await | 异步编程支持 |
占位 | pass | 空操作占位符 |
生成器 | yield | 生成器函数返回值 |
1.3.查看当前 Python 版本的所有保留字
import keyword
# 获取所有保留字列表
print("Python 保留字列表:")
print(keyword.kwlist)
# 检查单词是否为保留字
test_words = ["for", "while", "variable", "function"]
for word in test_words:
if keyword.iskeyword(word):
print(f"'{word}' 是保留字")
else:
print(f"'{word}' 不是保留字")
1.4.输出示例:
Python 保留字列表:
['False', 'None', 'True', 'and', 'as', 'assert', 'async', ...]
'for' 是保留字
'while' 是保留字
'variable' 不是保留字
'function' 不是保留字
2.标识符
标识符是程序员定义的名称,用于变量、函数、类、模块等对象的命名。
2.1.标识符命名规则
-
组成字符:
- 字母(a-z, A-Z)
- 数字(0-9)
- 下划线(_)
-
首字符限制:
- 不能以数字开头
- 可以以字母或下划线开头
-
大小写敏感:
myVar
和myvar
是不同的标识符
-
长度无限制:
- 但建议保持合理长度(通常不超过30字符)
-
避免保留字:
- 不能使用 Python 保留字作为标识符
2.2.合法标识符示例
# 有效标识符
counter = 10
user_name = "Alice"
calculate_total = lambda x, y: x + y
_is_valid = True
MAX_SIZE = 100 # 常量常用全大写
ClassRoom = "101" # 类名通常使用驼峰命名法
2.3.非法标识符示例
# 无效标识符(会引发 SyntaxError)
2nd_place = "silver" # 不能以数字开头
class = "Physics" # 使用保留字
user-name = "Bob" # 包含非法字符(-)
$price = 99.99 # 包含非法字符($)
2.4.Python 标识符命名规范
标识符类型 | 命名规范 | 示例 |
---|---|---|
变量名 | 小写字母 + 下划线 | user_count , total_amount |
函数名 | 小写字母 + 下划线 | calculate_total() , get_user_info() |
类名 | 驼峰式(首字母大写) | StudentRecord , DatabaseConnection |
常量名 | 全大写 + 下划线 | MAX_SIZE , PI_VALUE |
模块名 | 短小全小写 | utils.py , data_processor.py |
包名 | 短小全小写 | my_package/ |
私有成员 | 单下划线开头 | _internal_method() |
特殊方法 | 双下划线开头和结尾 | __init__() , __str__() |
2.5.特殊标识符约定
-
单下划线开头
_variable
:- 表示内部使用(弱私有)
from module import *
不会导入这些变量
-
双下划线开头
__variable
:- 名称修饰(Name Mangling),防止子类意外覆盖
- 实际会变为
_ClassName__variable
-
双下划线开头和结尾
__init__
:- Python 特殊方法标识符
- 用于运算符重载和内置功能实现
-
全大写命名
CONSTANT_VALUE
:- 约定表示常量(但 Python 没有真正的常量)
- 提示程序员不要修改此值
2.6.实践
-
描述性命名:
# 差 a = 10 b = calculate(x) # 好 user_count = 10 total_price = calculate_total(items)
-
避免混淆字符:
# 避免使用容易混淆的字符 O = 0 # 字母O vs 数字0 l = 1 # 字母l vs 数字1
-
保持一致性:
# 在同一个项目中保持统一风格 # 选择一种并坚持使用: customer_name = "Alice" # 下划线风格 customerName = "Bob" # 驼峰风格(不推荐在Python中使用)
-
避免内置名称:
# 不要覆盖内置函数/类型 list = [1, 2, 3] # 危险!覆盖了内置list
-
合理使用缩写:
# 常见缩写可接受 config = load_config() db_conn = create_db_connection() # 避免过度缩写 usr_cnt = 10 # 不清晰
3.保留字与标识符常见错误
错误1:使用保留字作为标识符
# 错误示例
class = "Physics 101" # SyntaxError: invalid syntax
# 解决方案
class_name = "Physics 101"
course = "Physics 101"
错误2:数字开头的标识符
# 错误示例
1st_place = "John" # SyntaxError: invalid decimal literal
# 解决方案
first_place = "John"
winner = "John"
错误3:使用特殊字符
# 错误示例
user@email = "test@example.com" # SyntaxError: invalid syntax
# 解决方案
user_email = "test@example.com"
email_address = "test@example.com"
错误4:大小写混淆
# 定义
Total = 100
# 使用
print(total) # NameError: name 'total' is not defined
# 解决方案:保持大小写一致
total = 100
print(total) # 正确
4.练习:识别有效标识符
# 判断下列哪些是有效标识符
identifiers = [
"username", # 有效
"_temp", # 有效
"2nd_place", # 无效(数字开头)
"class", # 无效(保留字)
"total$", # 无效(包含$)
"MAX_SIZE", # 有效
"is_valid?", # 无效(包含?)
"while", # 无效(保留字)
"__init__", # 有效(特殊方法)
"firstName" # 有效(但不推荐)
]
for ident in identifiers:
if ident.isidentifier() and not keyword.iskeyword(ident):
print(f"'{ident}' 是有效标识符")
else:
print(f"'{ident}' 是无效标识符")
变量与常量
在 Python 中,变量用于存储可变数据,常量则用于存储不应更改的值(通过约定实现)。
1.变量 (Variables)
-
定义
- 变量是存储数据的命名容器
- 使用
=
赋值:variable_name = value
- 示例:
age = 25 # 整数变量 name = "Alice" # 字符串变量 height = 1.75 # 浮点数变量 is_student = True # 布尔变量
-
特性
- 动态类型:变量类型在赋值时自动确定,可随时改变
x = 10 # x 是整数 x = "hi" # 现在 x 是字符串 合法
- 引用机制:变量指向对象的内存地址
a = [1, 2] b = a # b 和 a 指向同一个列表 b.append(3) print(a) # 输出 [1, 2, 3]
- 动态类型:变量类型在赋值时自动确定,可随时改变
-
命名规则
- 可包含字母、数字、下划线(不能以数字开头)
- 区分大小写:
age ≠ Age
- 避免关键字:
if
,for
,while
等 - 推荐蛇形命名法:
user_name
(PEP 8)
2.常量 (Constants)
-
定义
- Python 没有语法级别的常量
- 通过命名约定表示常量:全大写字母 + 下划线
PI = 3.14159 MAX_USERS = 100 API_KEY = "A1B2-C3D4"
-
特性
- 约定优于强制:技术上可修改,但开发者应遵守不修改的约定
PI = 3.14 PI = 4 # 语法允许,但逻辑错误(违反常量约定)
- 通常定义在模块顶层或单独文件中
- 约定优于强制:技术上可修改,但开发者应遵守不修改的约定
3.变量与常量对比
特性 | 变量 (Variables) | 常量 (Constants) |
---|---|---|
目的 | 存储可变数据 | 存储固定值(如配置参数) |
命名 | 小写+下划线 (user_id ) | 全大写 (MAX_SIZE ) |
可修改性 | 随时可重新赋值 | 约定不可修改 |
内存管理 | 引用计数 + 垃圾回收 | 同左 |
典型用途 | 循环计数器、临时计算结果 | 数学常数、配置参数 |
4.实践
-
变量使用技巧
- 避免无意义命名:用
student_count
而非x
- 类型提示(Python 3.6+):
name: str = "Bob" age: int = 30
- 删除无用变量:
del unused_var
- 避免无意义命名:用
-
常量管理方案
- 创建常量模块
constants.py
:# constants.py PI = 3.1415926535 DEFAULT_TIMEOUT = 60
- 导入使用:
from constants import PI print(PI * 2)
- 创建常量模块
-
特殊常量对象(需第三方库)
使用namedtuple
或dataclass
创建伪常量组:from collections import namedtuple Constants = namedtuple('Constants', ['PI', 'G']) consts = Constants(PI=3.14, G=9.8) # 尝试修改会报错:consts.PI = 3.15 AttributeError
5.注意事项
-
变量作用域
global_var = 10 def func(): local_var = 20 # 局部变量 global global_var # 声明全局变量 global_var = 30 print(global_var) # 输出 30 print(local_var) # NameError(局部变量外部不可访问)
-
常量冻结方案
使用frozenset
或元组创建不可变集合:COLORS = frozenset(["RED", "GREEN", "BLUE"]) # COLORS.add("YELLOW") AttributeError
数据类型
数值类型(Number)
Python 提供了三种核心数值类型,用于处理数学计算和科学运算:
1. 整数 (int
)
-
特点:
- 无大小限制(仅受内存限制)
- 支持十进制、二进制(
0b
)、八进制(0o
)、十六进制(0x
)
-
示例:
a = 42 # 十进制 b = 0b1010 # 二进制 → 10 c = 0o52 # 八进制 → 42 d = 0x2A # 十六进制 → 42 big_num = 10**100 # 超大整数(100位数)
2. 浮点数 (float
)
-
特点:
- 双精度浮点数(64位,遵循 IEEE 754 标准)
- 存在精度限制(15-17位有效数字)
- 支持科学计数法(
e
或E
)
-
示例:
pi = 3.1415926535 avogadro = 6.022e23 # 6.022 × 10²³ tiny = 1e-10 # 0.0000000001
3. 复数 (complex
)
-
特点:
- 格式:
实部 + 虚部j
- 虚部后缀必须是
j
或J
- 格式:
-
示例:
z = 3 + 4j # 实部=3, 虚部=4 print(z.real) # 输出 3.0 print(z.imag) # 输出 4.0
4. 布尔值 (bool
)
-
特点:
True
= 1,False
= 0(int
的子类)- 可直接参与数值运算
-
示例:
total = True + False + 10 # 结果 = 11
数值运算操作符
操作符 | 功能 | 示例 |
---|---|---|
+ | 加法 | 3 + 2 → 5 |
- | 减法 | 5 - 1 → 4 |
* | 乘法 | 2 * 3.5 → 7.0 |
/ | 真除法 | 10 / 3 → 3.333... |
// | 整除 | 10 // 3 → 3 |
% | 取模(余数) | 10 % 3 → 1 |
** | 幂运算 | 2 ** 4 → 16 |
@ | 矩阵乘法 | (Python 3.5+) |
5.数值运算常见问题
5.1. 浮点数精度问题
>>> 0.1 + 0.2
0.30000000000000004 # 非精确值
解决方案:
-
使用
round()
函数:round(0.1 + 0.2, 2) → 0.3
-
需要精确计算时使用
decimal
模块:from decimal import Decimal Decimal('0.1') + Decimal('0.2') # 精确得 0.3
5.2. 整数除法与浮点除法
10 / 3 # → 3.333... (浮点结果)
10 // 3 # → 3 (整数结果)
6.数值类型转换
函数 | 说明 | 示例 |
---|---|---|
int(x) | 转整数(截断小数) | int(3.9) → 3 |
float(x) | 转浮点数 | float(7) → 7.0 |
complex(x) | 转复数 | complex(5) → 5+0j |
round(x,n) | 四舍五入到n位小数 | round(3.14159, 2) → 3.14 |
7.常用数值函数
函数/模块 | 用途 | 示例 |
---|---|---|
abs(x) | 绝对值 | abs(-5) → 5 |
pow(x,y) | 幂运算 (等价于 x**y ) | pow(2,3) → 8 |
divmod(x,y) | 返回商和余数 | divmod(10,3) → (3,1) |
math 模块 | 高级数学函数 | math.sqrt(9) → 3.0 |
cmath 模块 | 复数数学函数 | cmath.sqrt(-1) → 1j |
random 模块 | 随机数生成 | random.randint(1,100) |
字符串(String)
在 Python 中,字符串(str) 是用于表示文本数据的不可变序列类型,使用单引号('
)、双引号("
)或三引号('''
/"""
)创建。
1. 字符串创建与基本操作
# 创建字符串
s1 = 'Hello' # 单引号
s2 = "Python" # 双引号
s3 = '''多行
字符串''' # 三引号(保留换行)
s4 = r"C:\new\folder" # 原始字符串(忽略转义)
基础操作:
# 拼接
full = s1 + " " + s2 # "Hello Python"
# 重复
stars = "★" * 5 # "★★★★★"
# 索引
char = s2[1] # 'y'(索引从0开始)
# 切片
sub = s2[2:5] # 'tho'([起始:结束:步长])
2. 字符串常用方法
方法 | 功能 | 示例 |
---|---|---|
str.upper()/lower() | 大小写转换 | "Py".upper() → "PY" |
str.strip() | 去除两端空白 | " text ".strip() → "text" |
str.split(sep) | 分割字符串 | "a,b,c".split(",") → ['a','b','c'] |
str.join(iterable) | 连接字符串序列 | ",".join(['1','2']) → "1,2" |
str.find(sub) | 查找子串位置 | "apple".find("p") → 1 |
str.replace(old,new) | 替换子串 | "tea".replace("t","c") → "cea" |
str.startswith(prefix) | 检查前缀 | "file.txt".startswith("file") → True |
str.format() | 格式化字符串 | "{}kg".format(5) → "5kg" |
str.isdigit() | 是否全数字字符 | "123".isdigit() → True |
3. 字符串格式化
1. % 格式化(传统方式)
name = "Alice"
print("Hello, %s! Age: %d" % (name, 25))
# 输出: Hello, Alice! Age: 25
2. str.format()(Python 2.6+)
print("坐标: ({x}, {y})".format(x=10, y=20))
# 输出: 坐标: (10, 20)
3. f-strings(Python 3.6+ 推荐)
price = 99.9
print(f"价格: ¥{price:.2f}") # 价格: ¥99.90
# 支持表达式: f"{2*3}=6"
4. 转义字符与原始字符串
转义序列 | 含义 | 转义序列 | 含义 |
---|---|---|---|
\n | 换行 | \\ | 反斜杠 |
\t | 水平制表符 | \' | 单引号 |
\r | 回车 | \" | 双引号 |
\uXXXX | Unicode 字符 | \xHH | 十六进制字符 |
原始字符串(忽略转义):
path = r"C:\Windows\System32" # 反斜杠不转义
regex = r"\d+" # 正则表达式常用
5. 字符串编码与Unicode
-
Python 3 默认使用 UTF-8 编码
-
字符串与字节转换:
# 字符串 → 字节 data = "中文".encode("utf-8") # b'\xe4\xb8\xad\xe6\x96\x87' # 字节 → 字符串 text = data.decode("utf-8") # "中文"
-
处理特殊字符:
print("\N{grinning face}") # print("\u4E2D") # 中 (Unicode码点)
6. 字符串不变性与内存优化
-
字符串不可变:创建后不能修改
s = "abc" # s[0] = "A" # 报错: TypeError new_s = "A" + s[1:] # 创建新对象
-
驻留机制:短字符串会重用内存
a = "hello!" b = "hello!" print(a is b) # True(小字符串内存相同)
7. 高级字符串处理技巧
多行字符串与缩进处理:
text = ("这是自动"
"连接的"
"多行字符串")
from textwrap import dedent
msg = dedent("""
自动去除
每行缩进
""")
字符串对齐:
"left".ljust(10) # 'left '
"right".rjust(10) # ' right'
"center".center(10) # ' center '
字符映射转换:
trans = str.maketrans("aeiou", "12345")
"apple".translate(trans) # "1ppl2"
8.注意事项
-
优先使用f-strings:简洁高效
-
避免字符串拼接循环:用
join()
代替# 低效 s = "" for i in range(1000): s += str(i) # 高效 parts = [str(i) for i in range(1000)] s = "".join(parts)
-
处理路径用
pathlib
代替字符串from pathlib import Path file = Path("dir") / "file.txt" # 跨平台路径
-
敏感操作注意编码:读写文件时显式指定编码
with open("data.txt", "w", encoding="utf-8") as f: f.write("多语言文本")
数据类型之间的转换
Python 提供了内置函数用于在不同数据类型间进行转换。
1.常用类型转换函数
函数 | 作用 | 可转换类型示例 | 注意事项 |
---|---|---|---|
int() | 转整数 | 数字字符串、浮点数、布尔值 | 非数字字符串会报 ValueError |
float() | 转浮点数 | 数字字符串、整数、布尔值 | 空字符串转换报错 |
str() | 转字符串 | 所有类型 | 总是成功,返回对象的字符串表示 |
bool() | 转布尔值 | 所有类型 | 遵循真值测试规则 |
list() | 转列表 | 元组、字符串、集合、字典键 | 字典默认转键列表 |
tuple() | 转元组 | 列表、字符串、集合、字典键 | 类似 list() |
set() | 转集合 | 列表、元组、字符串 | 自动去重 |
dict() | 转字典 | 键值对元组列表 | 需要特定结构 |
2.转换场景与示例
-
数值转换
# 字符串 → 整数/浮点数 print(int("42")) # 42 print(float("3.14")) # 3.14 # 浮点数 → 整数 (截断小数) print(int(9.99)) # 9 (非四舍五入) # 布尔值 → 数值 print(int(True)) # 1 print(float(False)) # 0.0
-
字符串转换
# 数值 → 字符串 print(str(100)) # "100" print(str(2.5e-3)) # "0.0025" # 容器 → 字符串 print(str([1, 2])) # "[1, 2]" print(str({"a": 1})) # "{'a': 1}"
-
布尔转换规则
# False 情况 print(bool(0)) # False print(bool(0.0)) # False print(bool("")) # False print(bool([])) # False print(bool({})) # False print(bool(None)) # False # True 情况 (其他所有值) print(bool(1)) # True print(bool(" ")) # True (空格也算非空) print(bool([0])) # True (非空列表)
-
容器类型互转
# 列表 ↔ 元组/集合 lst = [1, 2, 2] print(tuple(lst)) # (1, 2, 2) print(set(lst)) # {1, 2} (去重) # 字符串 → 列表 (字符拆分) print(list("hello")) # ['h', 'e', 'l', 'l', 'o'] # 转字典 (需可迭代键值对) print(dict([('a',1), ('b',2)])) # {'a':1, 'b':2}
3.特殊转换技巧
-
混合类型计算自动转换
# 整数 + 浮点数 → 浮点数 print(5 + 2.3) # 7.3 (float) # 字符串 + 数值 → 需显式转换 # print("Age: " + 25) # TypeError print("Age: " + str(25)) # "Age: 25"
-
进制转换
# 十六进制字符串 → 整数 print(int("FF", 16)) # 255 # 整数 → 十六进制字符串 print(hex(255)) # "0xff" # 整数 → 二进制字符串 print(bin(10)) # "0b1010"
-
ASCII/Unicode 转换
# 字符 → ASCII码 print(ord('A')) # 65 # ASCII码 → 字符 print(chr(65)) # 'A' # Unicode 转换 print(chr(0x1F600)) # (U+1F600)
4.转换失败处理
-
捕获异常
try: num = int("123abc") except ValueError as e: print(f"转换失败: {e}") # 输出错误信息
-
安全转换函数
def safe_int(value, default=0): try: return int(value) except (ValueError, TypeError): return default print(safe_int("42")) # 42 print(safe_int("abc")) # 0 (返回默认值)
-
类型检查
if isinstance(user_input, str) and user_input.isdigit(): num = int(user_input)
运算符
Python 提供了丰富的运算符类型,用于执行各种操作。下面我将系统性地介绍所有运算符类别及其用法:
1.算术运算符
运算符 | 名称 | 示例 | 结果 |
---|---|---|---|
+ | 加法 | 3 + 2 | 5 |
- | 减法 | 5 - 2 | 3 |
* | 乘法 | 3 * 4 | 12 |
/ | 除法 | 10 / 3 | 3.333 |
% | 取模 | 10 % 3 | 1 |
** | 幂运算 | 2 ** 3 | 8 |
// | 整除 | 10 // 3 | 3 |
特殊用法:
# 字符串拼接
print("Hello" + " World") # Hello World
# 列表合并
print([1, 2] + [3, 4]) # [1, 2, 3, 4]
# 字符串重复
print("A" * 5) # AAAAA
# 列表重复
print([0] * 3) # [0, 0, 0]
2.比较运算符
运算符 | 名称 | 示例 | 结果 |
---|---|---|---|
== | 等于 | 5 == 5 | True |
!= | 不等于 | 5 != 3 | True |
> | 大于 | 5 > 3 | True |
< | 小于 | 3 < 5 | True |
>= | 大于等于 | 5 >= 5 | True |
<= | 小于等于 | 3 <= 5 | True |
链式比较:
# 数学表达式直接转换
x = 5
print(1 < x < 10) # True
print(5 <= x <= 5) # True
3.赋值运算符
运算符 | 示例 | 等价于 |
---|---|---|
= | x = 5 | x = 5 |
+= | x += 3 | x = x + 3 |
-= | x -= 2 | x = x - 2 |
*= | x *= 4 | x = x * 4 |
/= | x /= 2 | x = x / 2 |
%= | x %= 3 | x = x % 3 |
//= | x //= 2 | x = x // 2 |
**= | x **= 2 | x = x ** 2 |
多重赋值:
# 同时给多个变量赋值
a, b, c = 1, 2, 3
# 变量交换(无需临时变量)
x, y = 10, 20
x, y = y, x # 交换后 x=20, y=10
4.逻辑运算符
运算符 | 名称 | 示例 | 结果 |
---|---|---|---|
and | 与 | True and False | False |
or | 或 | True or False | True |
not | 非 | not True | False |
短路求值特性:
def check():
print("函数被调用")
return True
# 第一个条件为False时,and后面的不会执行
False and check() # 无输出
# 第一个条件为True时,or后面的不会执行
True or check() # 无输出
5.位运算符
运算符 | 名称 | 示例 | 结果 |
---|---|---|---|
& | 按位与 | 0b1100 & 0b1010 | 0b1000 (8) |
| | 按位或 | 0b1100 | 0b1010 | 0b1110 (14) |
^ | 按位异或 | 0b1100 ^ 0b1010 | 0b0110 (6) |
~ | 按位取反 | ~0b1100 | -13 (补码表示) |
<< | 左移 | 5 << 1 | 10 |
>> | 右移 | 10 >> 1 | 5 |
实际应用场景:
# 奇偶判断
num = 15
if num & 1:
print("奇数") # 输出
# 快速乘除2的幂次
x = 7
print(x << 1) # 14 (7*2)
print(x >> 1) # 3 (7//2)
# 交换两个数(不使用临时变量)
a = 5; b = 3
a = a ^ b
b = a ^ b # b = (a^b)^b = a
a = a ^ b # a = (a^b)^a = b
6.成员运算符
运算符 | 名称 | 示例 | 结果 |
---|---|---|---|
in | 在序列中 | 'a' in 'apple' | True |
not in | 不在序列中 | 10 not in [1, 2, 3] | True |
支持的数据结构:
# 字符串
print("py" in "python") # True
# 列表
print(3 in [1, 2, 3]) # True
# 元组
print(4 in (1, 2, 3)) # False
# 字典(检查键)
d = {'a': 1, 'b': 2}
print('a' in d) # True
print(1 in d) # False
# 集合
s = {1, 2, 3}
print(2 in s) # True
7.身份运算符
运算符 | 名称 | 示例 | 结果 |
---|---|---|---|
is | 是同一对象 | a is b | 比较对象ID |
is not | 不是同一对象 | a is not b | 比较对象ID |
与==
的区别:
a = [1, 2, 3]
b = a # 引用同一个列表
c = [1, 2, 3] # 创建新列表
print(a == b) # True (值相同)
print(a is b) # True (同一对象)
print(a == c) # True (值相同)
print(a is c) # False (不同对象)
# 小整数池优化(-5到256)
x = 256
y = 256
print(x is y) # True
x = 257
y = 257
print(x is y) # False (不同对象)
8.三元条件运算符
# 语法:value_if_true if condition else value_if_false
# 传统写法
if x > 0:
result = "正数"
else:
result = "非正数"
# 三元运算符写法
result = "正数" if x > 0 else "非正数"
# 嵌套示例
grade = 'A' if score >= 90 else 'B' if score >= 80 else 'C' if score >= 70 else 'D'
9.海象运算符
# 语法: :=
# 在表达式中同时进行赋值和返回
# 传统写法
n = len(data)
if n > 10:
print(f"数据量过大: {n}")
# 使用海象运算符
if (n := len(data)) > 10:
print(f"数据量过大: {n}")
# 在循环中的应用
while (line := input("输入: ")) != "exit":
print(f"你输入了: {line}")
# 列表推导式中的应用
numbers = [1, 2, 3, 4, 5]
squared = [y := x**2 for x in numbers if y > 10]
print(squared) # [16, 25]
10.运算符优先级
从高到低排列:
()
- 括号**
- 指数~
- 按位取反*
,/
,%
,//
- 乘除+
,-
- 加减<<
,>>
- 位移&
- 按位与^
- 按位异或|
- 按位或==
,!=
,>
,<
,>=
,<=
- 比较is
,is not
,in
,not in
- 身份/成员not
- 逻辑非and
- 逻辑与or
- 逻辑或:=
- 海象运算符
11.实践:
# 当优先级不明确时,使用括号明确意图
result = (a + b) * (c - d) # 优于 a + b * c - d
# 复杂表达式分行
total = (value1 * factor1) + \
(value2 * factor2) + \
(value3 * factor3)
第4章:程序组织结构
1.顺序结构
定义:程序按代码书写顺序逐行执行,是最基本的程序结构。
流程图:
== 示例:==
# 顺序结构示例
print("步骤1:准备食材") # 1
print("步骤2:清洗食材") # 2
print("步骤3:烹饪处理") # 3
print("步骤4:装盘上菜") # 4
2.选择结构
2.1选择结构简介
定义:根据条件判断选择不同执行路径
核心语句:if
, elif
, else
流程图:
2.2if
语句
- 语法
age = 19
if age >= 18: # if 后面跟条件语句 再加上: 如果条件为真就执行执行语句,反之不然
print("是成年人") # 执行语句要缩进 默认4个空格
2.2if-else
语句
- 语法
age = 19
if age < 18: # age < 18 是条件语句
print("不是成年人")
else: # else跟在if后面表示,表示条件语句不成立时
print("是成年人") # 条件语句不成立时执行的代码
2.3if-elif-else
语句
Python 实现
- 代码
# 选择结构示例
score = 85
if score >= 90:
print("优秀")
elif score >= 80: # 这里elif是与if并列的,执行满足条件的一个
print("良好") # 输出此项
elif score >= 60:
print("及格")
else: # 不满足上述所有条件时执行
print("不及格")
- 输出
良好
2.4条件嵌套
顾名思义就是条件判断里面继续条件判断
Python实现
age = 18
sex = "男"
if age >= 18: # 先判断
if sex == "男": # 前一层满足 再判断
print("Good man!") # 条件均满足就执行
输出
Good man!
3.循环结构
定义:重复执行特定代码块直到满足终止条件
3.1. while
循环
流程图:
Python 实现
- 代码
# while循环示例
count = 0
while count < 5: # 首先进行判断 满足条件 执行缩进部分
print(f"当前计数: {count}")
count = count + 1 # 这里让count+1 count值变为1 仍满足条件 -->2 -->3 -->4 -->5 不满足退出循环
print("循环结束")
- 输出
当前计数: 0
当前计数: 1
当前计数: 2
当前计数: 3
当前计数: 4
循环结束
3.2. for
循环
流程图:
Python 实现
range()函数介绍
- range() 是 Python 中用于生成整数序列的内置函数,特别适用于循环操作。
3.2.1.range()
三种使用方式
语法形式 | 说明 | 示例 | 生成序列 |
---|---|---|---|
range(stop) | 0 到 stop-1 的整数 | range(5) | [0,1,2,3,4] |
range(start, stop) | start 到 stop-1 的整数 | range(2, 6) | [2,3,4,5] |
range(start, stop, step) | 从 start 开始,步长为 step | range(1, 10, 2) | [1,3,5,7,9] |
3.2.2range()
关键特性
-
惰性求值
直接打印 range 对象不显示具体值:print(range(5)) # 输出:range(0, 5)
-
支持负步长(倒序生成):
list(range(5, 0, -1)) # [5, 4, 3, 2, 1]
3.2.3.range()
常用场景
1. 基础循环
# 重复固定次数
for i in range(3):
print(f"执行第{i+1}次")
# 输出:
# 执行第1次
# 执行第2次
# 执行第3次
2. 遍历序列索引
colors = ["红", "绿", "蓝"]
for i in range(len(colors)):
print(f"索引{i}: {colors[i]}")
3. 生成等差数列
# 0~100的偶数
even_nums = list(range(0, 101, 2))
4. 倒序迭代
for i in range(10, 0, -1):
print(i) # 10,9,8...1
3.2.4进阶技巧
-
与
enumerate
结合获取索引值for idx, value in enumerate(["a", "b", "c"]): print(f"{idx}:{value}")
-
快速创建数字列表
squares = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
-
浮点数序列生成(需
numpy
或自定义)# 自定义浮点range def frange(start, stop, step): while start < stop: yield round(start, 2) start += step list(frange(0.1, 0.5, 0.1)) # [0.1, 0.2, 0.3, 0.4]
3.2.5注意事项
-
整数限制
参数必须是整数,不支持浮点:range(0.5, 2.5) # TypeError
-
步长不为零
range(1, 5, 0) # ValueError
-
空序列条件
当 start ≥ stop 且 step>0 时,返回空序列:list(range(5, 3)) # [] list(range(0)) # []
示例
- 代码
# for循环示例
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits: # 逐个遍历列表元素 "苹果" ,"香蕉","橙子"
print(f"我喜欢吃{fruit}")
print("所有水果已遍历")
- 输出
我喜欢吃苹果
我喜欢吃香蕉
我喜欢吃橙子
所有水果已遍历
4.结构嵌套示例
功能:查找1-100中能被3整除的偶数
流程图:
Python 实现
- 代码
for num in range(1, 101):
if num % 2 == 0: # 选择结构嵌套在循环内
if num % 3 == 0: # 嵌套选择结构
print(f"{num} 是能被3整除的偶数")
- 输出
6 是能被3整除的偶数
12 是能被3整除的偶数
18 是能被3整除的偶数
24 是能被3整除的偶数
30 是能被3整除的偶数
36 是能被3整除的偶数
42 是能被3整除的偶数
48 是能被3整除的偶数
54 是能被3整除的偶数
60 是能被3整除的偶数
66 是能被3整除的偶数
72 是能被3整除的偶数
78 是能被3整除的偶数
84 是能被3整除的偶数
90 是能被3整除的偶数
96 是能被3整除的偶数
5.三种结构对比
结构类型 | 特点 | 适用场景 | 核心关键字 |
---|---|---|---|
顺序结构 | 线性执行,无分支跳转 | 简单流程处理 | 无特殊关键字 |
选择结构 | 根据条件选择执行路径 | 条件判断、分支处理 | if , elif , else |
循环结构 | 重复执行特定代码块 | 遍历数据、重复操作 | while , for , break , continue |
- 单一入口/出口:每个结构只有一个入口和一个出口
- 避免深层嵌套:嵌套层级不超过3层
- 循环优化:尽量减少循环内的复杂操作
- 条件简化:复杂条件判断可拆分为多个变量
6.break 和 continue
break
:用于跳出循环的一层
continue
:用于跳出一次循环
示例
- 代码
for i in range(10):
if i % 2 == 0: # 如果i是偶数本次循环就结束了
continue
elif i == 5: # 如果i的值为5,那么整个循环就结束了
break
print(i) # i是偶数循环就执行不到这来 但是循环会继续,i是5循环就结束了
- 输出
1
3
7.pass
pass
表示空语句,什么也不会执行
pass
是 Python 中的一个特殊语句,它表示空操作或占位符。当语法上需要语句但程序不需要任何操作时使用 pass
。
7.1 核心作用
7.1.1. 语法占位符(主要用途)
当代码块中需要语句但逻辑上不需要操作时,使用 pass
避免语法错误:
def future_feature():
pass # 待实现的功能
class AbstractClass:
def must_implement(self):
pass # 子类必须重写此方法
7.1.2. 空循环体
创建不做任何操作的循环:
# 等待用户中断 (Ctrl+C)
while True:
pass
7.1.3. 空条件分支
处理不需要操作的条件分支:
if condition:
do_something()
else:
pass # 明确表示不执行任何操作
7.1.4. 空上下文管理器
定义不需要操作的上下文管理器:
class DummyLock:
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
pass
# 使用
with DummyLock():
# 不需要实际加锁的操作
process_data()
7.2总结
pass
的核心作用:
- 语法占位:满足 Python 的语法要求
- 意图表达:明确表示"此处不需要任何操作"
- 临时标记:标识待实现代码位置
第5章:Python容器
1.列表(List)
在 Python 中,列表(list) 是最重要的数据结构之一,它是一种有序、可变的容器,可以存储任意类型的元素(支持混合类型),并通过索引访问元素。
1.1 列表创建与基本操作
# 创建列表
empty = [] # 空列表
numbers = [1, 2, 3, 4] # 整数列表
mixed = [10, "text", True] # 混合类型列表
nested = [[1, 2], [3, 4]] # 嵌套列表
基础操作:
# 索引访问
first = numbers[0] # 1 (正向索引从0开始)
last = numbers[-1] # 4 (负索引表示从末尾开始)
# 切片操作
subset = numbers[1:3] # [2, 3] [起始:结束:步长]
reverse = numbers[::-1] # [4, 3, 2, 1] (反转列表)
# 长度检查
length = len(numbers) # 4
1.2. 列表的突变性
列表是可变对象,支持原地修改:
# 修改元素
numbers[0] = 100 # [100, 2, 3, 4]
# 添加元素
numbers.append(5) # 末尾添加 → [100, 2, 3, 4, 5]
numbers.insert(1, 1.5) # 指定位置插入 → [100, 1.5, 2, 3, 4, 5]
# 删除元素
del numbers[0] # 删除索引0 → [1.5, 2, 3, 4, 5]
numbers.remove(3) # 删除第一个匹配值 → [1.5, 2, 4, 5]
popped = numbers.pop() # 删除并返回末尾元素 → popped=5, numbers=[1.5,2,4]
1.3. 核心列表方法
方法 | 功能 | 示例 |
---|---|---|
list.append(x) | 末尾添加元素 | [1].append(2) → [1,2] |
list.extend(iter) | 合并另一个可迭代对象 | [1,2].extend([3,4]) → [1,2,3,4] |
list.insert(i,x) | 指定位置插入 | [1,3].insert(1,2) → [1,2,3] |
list.remove(x) | 删除第一个匹配元素 | [1,2,1].remove(1) → [2,1] |
list.pop([i]) | 删除并返回指定位置元素(默认末尾) | [1,2,3].pop(0) → 1, 列表变为[2,3] |
list.clear() | 清空列表 | [1,2].clear() → [] |
list.index(x) | 返回元素索引 | ['a','b'].index('b') → 1 |
list.count(x) | 统计元素出现次数 | [1,1,2].count(1) → 2 |
list.sort() | 原地排序 | [3,1,2].sort() → [1,2,3] |
list.reverse() | 原地反转列表 | [1,2,3].reverse() → [3,2,1] |
list.copy() | 浅拷贝列表 | new = old.copy() |
1.4. 列表操作技巧
1. 列表推导式(高效创建)
# 创建平方数列表
squares = [x**2 for x in range(5)] # [0,1,4,9,16]
# 带条件的推导式
evens = [x for x in range(10) if x % 2 == 0] # [0,2,4,6,8]
# 嵌套推导式
matrix = [[1,2], [3,4]]
flat = [num for row in matrix for num in row] # [1,2,3,4]
2. 列表合并与重复
# 合并
combined = [1, 2] + ['a', 'b'] # [1,2,'a','b']
# 重复
zeros = [0] * 5 # [0,0,0,0,0]
3. 元素存在性检查
if 3 in numbers:
print("3 exists")
if 99 not in numbers:
print("99 not found")
1.5. 列表与内存管理
-
可变性陷阱:多个变量引用同一列表时
a = [1, 2] b = a # b 和 a 指向同一对象 b.append(3) print(a) # [1,2,3] (a也被修改)
-
正确复制列表:
# 浅拷贝方法 copy1 = original.copy() copy2 = list(original) copy3 = original[:] # 深拷贝(嵌套列表需要) import copy deep_copy = copy.deepcopy(nested_list)
1.6. 高级列表操作
1. 排序与自定义排序
# 简单排序
nums = [3, 1, 4, 2]
nums.sort() # 原地排序 [1,2,3,4]
# 降序排序
nums.sort(reverse=True) # [4,3,2,1]
# 自定义排序
words = ["apple", "Fig", "banana"]
words.sort(key=str.lower) # 忽略大小写排序
2. 枚举遍历
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"Index {index}: {fruit}")
3. 使用zip并行遍历
names = ["Alice", "Bob"]
scores = [85, 92]
for name, score in zip(names, scores):
print(f"{name}: {score}")
1.7.注意事项
-
时间复杂度:
- 索引访问/修改:O(1)
- 末尾添加/删除:O(1)
- 中间插入/删除:O(n)
-
替代数据结构:
- 频繁首部操作 →
collections.deque
- 大量成员检查 →
set
- 只读序列 →
tuple
- 频繁首部操作 →
-
使用生成器处理大数据:
# 文件行处理 with open("large.txt") as f: lines = (line.strip() for line in f) # 生成器表达式 for line in lines: process(line)
2.元组(Tuple)
元组(tuple)是 Python 的核心数据类型之一,它是一种有序、不可变的序列。与列表不同,元组创建后内容无法修改,这使得它在某些场景下具有独特优势。
2.1. 元组创建与基本操作
# 创建元组
empty = () # 空元组
single = (42,) # 单元素元组(必须有逗号)
colors = ("red", "green", "blue") # 标准元组
mixed = (1, "text", 3.14, True) # 混合类型元组
nested = ((1, 2), [3, 4]) # 嵌套结构(可包含可变元素)
括号是可选的(逗号才是关键):
point = 10, 20 # 自动识别为元组 (10, 20)
基础操作:
# 索引访问
first_color = colors[0] # "red"
# 切片操作
sub_colors = colors[1:] # ("green", "blue")
# 长度检查
length = len(colors) # 3
# 成员检查
if "red" in colors:
print("红色存在")
2.2. 元组的不可变性
元组一旦创建,无法修改其内容:
t = (1, 2, 3)
# t[0] = 10 # 报错: TypeError
但若元组包含可变对象(如列表),这些对象可以修改:
nest = (1, [2, 3])
nest[1].append(4) # 合法 → (1, [2, 3, 4])
2.3. 元组与列表的转换
# 列表 → 元组
list_data = [1, 2, 3]
tuple_data = tuple(list_data) # (1, 2, 3)
# 元组 → 列表
tuple_info = ("a", "b", "c")
list_info = list(tuple_info) # ['a', 'b', 'c']
2.4. 元组解包
基础解包:
x, y, z = (10, 20, 30)
print(x, y, z) # 10 20 30
星号解包(Python 3.0+):
first, *middle, last = (1, 2, 3, 4, 5)
print(middle) # [2, 3, 4](中间部分转为列表)
函数返回多值:
def get_dimensions():
return 1920, 1080 # 隐式返回元组
width, height = get_dimensions()
交换变量值:
a = 5
b = 10
a, b = b, a # 无需临时变量
2.5. 元组常用方法
由于不可变性,元组方法比列表少:
方法 | 功能 | 示例 |
---|---|---|
tuple.count(x) | 统计元素出现次数 | (1,1,2).count(1) → 2 |
tuple.index(x) | 返回元素首次出现的位置 | ('a','b','c').index('b') → 1 |
len(tuple) | 获取长度 | len((1,2,3)) → 3 |
min()/max() | 获取最值 | max((10,20,5)) → 20 |
2.6. 元组性能优势
-
内存效率:元组比列表占用更少内存
import sys list_size = sys.getsizeof([1,2,3]) # 约 88 bytes tuple_size = sys.getsizeof((1,2,3)) # 约 64 bytes
-
创建速度:元组初始化比列表快 5-10 倍
-
字典键支持:元组(若元素不可变)可作为字典键,列表不行
valid_dict = {(1, 2): "坐标"} # 合法 # invalid_dict = {[1,2]: "值"} # 报错: unhashable type
2.7.元组的典型应用场景
2.7.1. 数据记录
# 人员信息 (姓名, 年龄, 职业)
person = ("Alice", 30, "工程师")
# 数据库查询结果
users = [
(1, "张三", "北京"),
(2, "李四", "上海")
]
2.7.2. 函数多返回值
def analyze_data(data):
min_val = min(data)
max_val = max(data)
avg_val = sum(data)/len(data)
return min_val, max_val, avg_val # 返回元组
stats = analyze_data([10, 20, 15])
2.7.3. 常量集合
# 方向常量
DIRECTIONS = ("NORTH", "SOUTH", "EAST", "WEST")
# 配置参数
DB_CONFIG = ("localhost", 3306, "user", "pass")
2.7.4. 字典键值
# 坐标映射
coordinate_map = {
(35, 139): "东京",
(40, -74): "纽约"
}
print(coordinate_map[(40, -74)]) # "纽约"
2.8.高级技巧与注意事项
2.8.1. 命名元组
from collections import namedtuple
# 定义类
Person = namedtuple("Person", "name age job")
# 创建实例
alice = Person("Alice", 30, "工程师")
print(alice.name) # "Alice" (类似对象属性)
print(alice[1]) # 30 (保留元组索引)
2.8.2. 元组与不可变性
t = ([1, 2], 3)
t[0].append(3) # 合法 → ([1,2,3], 3)
# 真正的不可变元组需所有元素不可变
immutable = (1, "text", (4, 5)) # 完全不可变
2.8.3. 空元组陷阱
empty = () # 正确空元组
not_empty = (42) # 整数 42(不是元组!)
is_tuple = (42,) # 单元素元组
2.9.元组与列表
特性 | 元组 | 列表 |
---|---|---|
可变性 | 不可变 | 可变 |
内存占用 | 较小 | 较大 |
性能 | 创建/访问更快 | 稍慢 |
字典键支持 | 支持 | 不支持 |
方法数量 | 2个 (count, index) | 11+个 |
适用场景 | 数据记录、常量、字典键、返回值 | 动态集合、需修改的数据 |
3.集合(Set)
集合(Set)是 Python 中一种无序、不重复元素的容器,基于哈希表实现,支持高效的成员检测和集合运算。集合分为可变集合 set
和不可变集合 frozenset
。
3.1. 集合创建与基本操作
# 创建集合
empty_set = set() # 空集合(不能用 {},那是字典)
fruits = {"apple", "banana", "cherry"} # 字面量创建
numbers = set([1, 2, 2, 3, 3]) # 从列表创建 → {1, 2, 3}
# 不可变集合
fs = frozenset([10, 20, 30]) # 无法修改
核心特性:
-
无序性:元素无固定顺序
-
唯一性:自动去重
-
可哈希性:元素必须是不可变类型
valid = {1, "text", (1, 2)} # 合法 # invalid = {[1, 2]} # 报错: unhashable type 'list'
3.2. 集合基本操作
操作 | 方法/运算符 | 示例 | 结果 |
---|---|---|---|
添加元素 | add() | fruits.add("orange") | {"apple", "banana", "cherry", "orange"} |
批量添加 | update() | fruits.update(["kiwi", "mango"]) | 添加多个元素 |
删除元素 | remove() | fruits.remove("banana") | 删除指定元素(不存在报错) |
安全删除 | discard() | fruits.discard("grape") | 删除元素(不存在不报错) |
随机弹出 | pop() | fruits.pop() | 随机移除一个元素 |
清空集合 | clear() | fruits.clear() | set() |
元素数量 | len() | len(fruits) | 3 |
3.3. 集合关系运算
运算 | 方法 | 运算符 | 描述 |
---|---|---|---|
并集 | union() | ` | ` |
交集 | intersection() | & | 共有元素 |
差集 | difference() | - | 仅存在于第一个集合的元素 |
对称差集 | symmetric_diff() | ^ | 不同时存在于两个集合的元素 |
子集检查 | issubset() | <= | 是否子集 |
真子集检查 | - | < | 是否真子集 |
超集检查 | issuperset() | >= | 是否超集 |
无交集检查 | isdisjoint() | - | 是否无共同元素 |
示例:
A = {1, 2, 3}
B = {3, 4, 5}
print(A | B) # {1, 2, 3, 4, 5} (并集)
print(A & B) # {3} (交集)
print(A - B) # {1, 2} (差集)
print(A ^ B) # {1, 2, 4, 5} (对称差集)
print(A <= {1,2,3,4}) # True (子集检查)
3.4. 集合推导式
类似列表推导式,生成集合:
# 生成平方数集合
squares = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
# 带条件的推导式
odds = {x for x in range(10) if x % 2 != 0} # {1, 3, 5, 7, 9}
3.5. 集合应用场景
1. 高效去重
names = ["Alice", "Bob", "Alice", "Charlie"]
unique_names = set(names) # {"Alice", "Bob", "Charlie"}
2. 成员快速检测(O(1)时间复杂度)
valid_users = {"user1", "user2", "admin"}
if input_username in valid_users: # 比列表快100倍+
grant_access()
3. 数据关系分析
# 找出两篇文章共有的词汇
article1_words = set(text1.split())
article2_words = set(text2.split())
common_words = article1_words & article2_words
4. 过滤重复项
# 在循环中跟踪已处理项
processed = set()
for item in data_stream:
if item not in processed:
process(item)
processed.add(item)
3.6. 不可变集合
- 可哈希,可用作字典键或集合元素
- 创建后无法修改
# 作为字典键
permissions = {
frozenset(["read"]): "基础权限",
frozenset(["read", "write"]): "编辑权限"
}
# 嵌套集合
graph = {
frozenset(["A", "B"]): 10,
frozenset(["B", "C"]): 15
}
3.7. 集合性能特点
操作 | 时间复杂度 | 说明 |
---|---|---|
添加元素 | O(1) | 平均情况 |
删除元素 | O(1) | 平均情况 |
成员检测 | O(1) | 主要优势 |
并集/交集 | O(len(s)+len(t)) | 取决于集合大小 |
遍历 | O(n) | n为元素数量 |
3.8.集合列表元组
特性 | 集合 (Set) | 列表 (List) | 元组 (Tuple) |
---|---|---|---|
有序性 | 无序 | 有序 | 有序 |
可变性 | 可以 (set) / 不可以 (frozenset) | 可变 | 不可变 |
重复元素 | 自动去重 | 允许重复 | 允许重复 |
查找速度 | O(1) | O(n) | O(n) |
内存占用 | 中等 | 较高 | 较低 |
典型用途 | 去重、成员检测 | 动态数据集合 | 固定数据记录 |
4.字典(Dictionary)
字典(dict)是 Python 中最强大的数据结构之一,它是一种可变、无序的键值对集合。字典通过键(key)进行高效查找,时间复杂度为 O(1),是 Python 高性能数据处理的核心工具。
4.1. 字典创建与基础
# 创建字典
empty_dict = {} # 空字典
person = {"name": "Alice", "age": 30, "city": "Paris"} # 字面量创建
squares = {x: x**2 for x in range(5)} # 字典推导式 → {0:0, 1:1, 2:4, 3:9, 4:16}
# 使用构造函数
colors = dict(red="#FF0000", green="#00FF00") # {'red':'#FF0000', 'green':'#00FF00'}
核心特性:
- 键唯一性:键必须唯一
- 键不可变性:键必须是不可变类型(字符串、数字、元组)
- 无序性:Python 3.7+ 保留插入顺序
- 高效查找:基于哈希表实现,O(1) 时间访问
4.2. 字典基本操作
操作 | 语法/方法 | 示例 | 结果 |
---|---|---|---|
访问元素 | dict[key] | person["name"] | "Alice" |
安全访问 | dict.get(key, default) | person.get("job", "N/A") | "N/A" |
添加/修改元素 | dict[key] = value | person["job"] = "Engineer" | 添加新键值对 |
删除元素 | del dict[key] | del person["city"] | 删除键值对 |
弹出元素 | dict.pop(key[, default]) | age = person.pop("age") | 移除并返回值 |
检查键存在 | key in dict | "name" in person | True |
获取所有键 | dict.keys() | list(person.keys()) | ['name','age',...] |
获取所有值 | dict.values() | list(person.values()) | ['Alice',30,...] |
获取键值对 | dict.items() | list(person.items()) | [('name','Alice'),...] |
4.3. 字典常用方法
方法 | 功能 | 示例 |
---|---|---|
dict.update(other_dict) | 合并字典(覆盖重复键) | person.update({"age":31, "country":"FR"}) |
dict.setdefault(key, default) | 键存在返回值,不存在插入默认值 | person.setdefault("age", 25) → 30 |
dict.popitem() | 移除并返回最后插入的键值对(LIFO) | person.popitem() → ('city','Paris') |
dict.clear() | 清空字典 | person.clear() → {} |
dict.copy() | 浅拷贝字典 | new_dict = person.copy() |
dict.fromkeys(seq, value) | 从序列创建字典(值相同) | dict.fromkeys(['a','b'], 0) → {'a':0,'b':0} |
4.4. 字典进阶技巧
1. 合并字典(Python 3.5+)
dict1 = {"a": 1}
dict2 = {"b": 2}
merged = {**dict1, **dict2} # {'a':1, 'b':2}
2. 默认值处理
# 统计词频
text = "apple banana apple cherry"
count = {}
for word in text.split():
count[word] = count.get(word, 0) + 1
# {'apple':2, 'banana':1, 'cherry':1}
3. 使用 defaultdict 简化代码
from collections import defaultdict
dd = defaultdict(list) # 默认值为空列表
dd["fruits"].append("apple") # 自动初始化
4. 字典视图对象
keys = person.keys() # 动态视图(非静态拷贝)
person["email"] = "alice@example.com"
print(keys) # 包含新键 'email'
4.5. 字典应用场景
1. 数据记录与配置
user_profile = {
"id": 12345,
"username": "alice_dev",
"preferences": {"theme": "dark", "notifications": True}
}
2. 高效查找表
# 颜色编码查找
COLOR_CODES = {
"red": "#FF0000",
"green": "#00FF00",
"blue": "#0000FF"
}
print(COLOR_CODES["blue"]) # "#0000FF"
3. JSON 数据处理
import json
data = json.loads('{"name": "Alice", "age": 30}') # 转为字典
json_str = json.dumps(person) # 转为JSON字符串
4. 缓存实现(Memoization)
cache = {}
def expensive_calculation(n):
if n not in cache:
cache[n] = n * n # 模拟耗时计算
return cache[n]
4.6. 高级字典类型
类型 | 来源 | 特点 | 使用场景 |
---|---|---|---|
OrderedDict | collections | 保留插入顺序(Python 3.7前需要) | 需要顺序保证的操作 |
defaultdict | collections | 自动初始化缺失键 | 分组统计、避免KeyError |
ChainMap | collections | 合并多个字典(逻辑视图) | 配置优先级处理 |
Counter | collections | 计数专用字典 | 频率统计、计数 |
UserDict | collections | 创建自定义字典的基类 | 扩展字典功能 |
示例:
from collections import Counter, defaultdict
# 计数
words = ["apple", "banana", "apple"]
count = Counter(words) # {'apple':2, 'banana':1}
# 分组
grouped = defaultdict(list)
for num in [1, 2, 1, 3]:
grouped[num].append(num) # {1:[1,1], 2:[2], 3:[3]}
4.7. 字典性能特点
操作 | 时间复杂度 | 说明 |
---|---|---|
获取元素 | O(1) | 主要优势 |
添加元素 | O(1) | 平均情况 |
删除元素 | O(1) | 平均情况 |
遍历字典 | O(n) | n为键值对数量 |
空间占用 | 较高 | 哈希表需要额外空间 |
4.8.字典列表集合
特性 | 字典 (Dict) | 列表 (List) | 集合 (Set) |
---|---|---|---|
数据结构 | 键值对 | 有序序列 | 唯一元素集合 |
访问方式 | 键(O(1)) | 索引(O(1)) | 成员检测(O(1)) |
可变性 | 可变 | 可变 | 可以 (set) / 不可以(frozenset) |
元素要求 | 键必须可哈希 | 无限制 | 元素必须可哈希 |
内存占用 | 较高 | 中等 | 中等 |
典型用途 | 键值映射、配置 | 有序数据集合 | 去重、集合运算 |
4.9.注意事项
1. 键不存在错误
# 错误:KeyError
# print(person["job"])
# 解决方案:
print(person.get("job", "Unemployed"))
2. 可变对象作为键
# 错误:不可哈希类型
# invalid_dict = {[1,2]: "value"}
# 解决方案:
valid_dict = {tuple([1,2]): "value"}
3. 遍历时修改字典
# 错误:RuntimeError
# for k in d: d.pop(k)
# 解决方案:
for k in list(d.keys()): # 先复制键
d.pop(k)
4. 浅拷贝问题
original = {"data": [1,2,3]}
copy = original.copy()
copy["data"].append(4) # 修改影响原字典
# 解决方案:
from copy import deepcopy
safe_copy = deepcopy(original)
第6章:正则表达式
正则表达式含义
正则表达式(Regular Expression,常缩写为 Regex 或 RegExp)是一种用于匹配、查找和替换文本模式的工具。它通过特定的字符组合形成模式字符串,可以高效地处理复杂的文本操作。
- 核心作用
- 文本匹配:验证字符串是否符合特定格式(如邮箱、手机号)。
- 文本查找:在大量文本中定位符合条件的片段。
- 文本替换:将匹配的部分替换为其他内容。
- 文本分割:根据特定模式分割字符串。
1.re模块
- 在使用re模块的时候需要先导入re模块
import re
# 这里就可以使用re模块中的函数
re可以通过一些特殊的字符进行进行许多字符的匹配下面是元字符表,即一些元字符表示含义的表:
模式 | 说明 | 示例 | 匹配结果 |
---|---|---|---|
. | 任意字符(除换行符) | a.c | “abc”, “a c” |
\d | 数字 [0-9] | \d{3} | “123” |
\w | 单词字符 [a-zA-Z0-9_] | \w+ | “user123” |
\s | 空白字符 | \s+ | 空格/制表符 |
[...] | 字符集合 | [aeiou] | “a”, “e”, "i"等 |
[^...] | 排除字符 | [^0-9] | 非数字字符 |
* | 0次或多次 | ab*c | “ac”, “abc” |
+ | 1次或多次 | ab+c | “abc”, “abbc” |
? | 0次或1次 | colou?r | “color”, “colour” |
{m,n} | m到n次重复 | a{2,4} | “aa”, “aaa” |
^ | 字符串开头 | ^Start | “Start…” |
$ | 字符串结尾 | end$ | “…end” |
\b | 单词边界 | \bword\b | "word"单独出现 |
| | 或运算符 | cat|dog | “cat"或"dog” |
1.1re.match()
Python 的 re.match()
函数用于从字符串的起始位置开始尝试匹配一个正则表达式模式。
它的核心作用和行为如下:
- 起始位置匹配: 这是
re.match()
最关键的特性。它只检查字符串的开头是否符合给定的正则表达式模式。即使模式能在字符串的中间或结尾找到匹配,只要开头不匹配,re.match()
就会返回None
。 - 返回匹配对象: 如果字符串的起始部分成功匹配了模式,
re.match()
返回一个Match
对象。这个对象包含了匹配的信息,例如匹配到的具体字符串、匹配的起止位置等。 - 返回
None
: 如果字符串的开头不匹配给定的模式,re.match()
返回None
。 - 单次匹配: 它只尝试匹配一次,从字符串的开头开始,找到第一个匹配(如果开头匹配)就返回。它不会扫描整个字符串去寻找所有可能的匹配(这是
re.findall()
或re.finditer()
的工作)。 - 区分大小写(默认): 默认情况下,匹配是区分大小写的。如果需要不区分大小写,可以在编译正则表达式时使用
re.IGNORECASE
标志(或简写为re.I
)作为flags
参数传递给re.match()
。
函数原型:
re.match(pattern, string, flags=0)
pattern
: 要匹配的正则表达式(字符串形式或已编译的正则表达式对象)。string
: 要在其中查找匹配的源字符串。flags
(可选): 用于修改正则表达式匹配行为的标志(如re.IGNORECASE
,re.MULTILINE
等)。默认值为 0,表示没有特殊标志。
示例
import re
# 示例 1: 匹配成功 (开头匹配)
text1 = "apple banana cherry"
match1 = re.match("apple", text1) # 匹配 'apple' 在开头
if match1:
print("Match found:", match1.group()) # 输出: Match found: apple
else:
print("No match")
# 示例 2: 匹配失败 (模式不在开头)
text2 = "banana apple cherry"
match2 = re.match("apple", text2) # 'apple' 不在开头
if match2:
print("Match found:", match2.group())
else:
print("No match") # 输出: No match
# 示例 3: 使用 re.search() 在任意位置查找 (对比)
text3 = "banana apple cherry"
search_result = re.search("apple", text3) # 扫描整个字符串
if search_result:
print("Search found:", search_result.group()) # 输出: Search found: apple
else:
print("No search match")
# 示例 4: 匹配数字开头
text4 = "123 Main Street"
match4 = re.match(r"\d+", text4) # 匹配开头的一个或多个数字
if match4:
print("Starts with numbers:", match4.group()) # 输出: Starts with numbers: 123
# 示例 5: 使用标志忽略大小写
text5 = "Apple pie"
match5 = re.match("apple", text5, re.IGNORECASE) # 忽略大小写,开头匹配
if match5:
print("Match (case-insensitive):", match5.group()) # 输出: Match (case-insensitive): Apple
总结:
当你需要验证一个字符串是否以特定的模式开头时,re.match()
是最合适的选择。例如:
- 检查字符串是否以 “http://” 或 “https://” 开头(URL 协议)。
- 检查字符串是否以数字开头。
- 检查日志条目是否以特定的时间戳格式开头。
- 验证用户输入是否以预期的命令或关键字开头。
如果需要在字符串的任意位置查找匹配,则应使用 re.search()
。
1.2re.search() 和 re.findall()
这两个函数都是 Python re
模块中用于正则表达式匹配的重要函数,但它们的行为和用途有显著区别:
re.search(pattern, string, flags=0)
核心功能:
- 扫描整个字符串,查找第一个匹配正则表达式的位置
- 不要求匹配必须从字符串开头开始(与
re.match()
不同)
返回值:
- 如果找到匹配,返回一个
Match
对象 - 如果没找到匹配,返回
None
特点:
- 只返回第一个匹配结果
- 通过
Match
对象可以获取详细信息:group()
:匹配的字符串start()
/end()
:匹配的位置span()
:匹配的起止位置元组
示例:
import re
text = "Contact: email@example.com, phone: 123-456-7890"
result = re.search(r'\d{3}-\d{3}-\d{4}', text)
if result:
print("Phone found:", result.group()) # 输出: Phone found: 123-456-7890
print("Starts at:", result.start()) # 输出: Starts at: 29
print("Ends at:", result.end()) # 输出: Ends at: 41
else:
print("No phone found")
re.findall(pattern, string, flags=0)
核心功能:
- 查找所有匹配正则表达式的子串
- 返回所有非重叠匹配的列表
返回值:
- 返回匹配字符串的列表
- 如果模式中有捕获组,返回捕获组内容的元组列表
- 如果没有匹配,返回空列表
[]
特点:
- 返回所有匹配结果
- 结果以列表形式直接返回,不包含位置信息
- 当模式中有分组时,行为会变化
示例:
import re
text = "Emails: user1@domain.com, user2@test.org, admin@server.net"
# 查找所有电子邮件
emails = re.findall(r'\b[\w.-]+@[\w.-]+\.\w+\b', text)
print("All emails:", emails)
# 输出: ['user1@domain.com', 'user2@test.org', 'admin@server.net']
# 带分组的查找(返回用户名和域名)
email_parts = re.findall(r'\b([\w.-]+)@([\w.-]+\.\w+)\b', text)
print("Email parts:", email_parts)
# 输出: [('user1', 'domain.com'), ('user2', 'test.org'), ('admin', 'server.net')]
关键区别总结
特性 | re.search() | re.findall() |
---|---|---|
匹配次数 | 只找第一个匹配 | 查找所有匹配 |
返回值类型 | Match 对象 或 None | 字符串列表 或 元组列表 |
返回内容 | 匹配对象(包含详细信息) | 匹配字符串或分组内容 |
位置信息 | 包含 (start/end/span) | 不包含 |
模式中有分组时 | 可通过 group(n) 访问 | 返回分组元组而非完整匹配 |
性能 | 找到第一个匹配即停止 | 扫描整个字符串查找所有匹配 |
典型用途 | 检查是否存在匹配/获取第一个匹配 | 提取所有匹配项/批量数据采集 |
1.3re.sub() 和 re.split()
这两个函数是 Python re
模块中用于字符串处理的核心工具,功能互补但用途不同:
re.sub()
- 正则替换
核心功能:
在字符串中查找匹配正则表达式的部分,并替换为指定内容
函数原型:
re.sub(pattern, repl, string, count=0, flags=0)
参数说明:
pattern
:要匹配的正则表达式repl
:替换内容(可以是字符串或函数)string
:输入字符串count
:最大替换次数(默认0=全部替换)flags
:正则标志(如re.IGNORECASE
)
重要特性:
-
支持反向引用:在替换字符串中使用
\g<name>
或\1
引用匹配分组# 格式化电话号码 phone = "123-456-7890" formatted = re.sub(r'(\d{3})-(\d{3})-(\d{4})', r'(\1) \2-\3', phone) # 结果: (123) 456-7890
-
函数替换:
repl
可以是函数,接收 Match 对象并返回字符串def to_upper(match): return match.group(0).upper() text = "hello world" result = re.sub(r'\b\w+\b', to_upper, text) # 结果: HELLO WORLD
-
计数控制:通过
count
参数限制替换次数text = "a a a a" result = re.sub(r'a', 'b', text, count=2) # 结果: "b b a a"
应用场景:
- 数据清洗(移除特殊字符)
- 文本格式化
- 敏感信息脱敏
- 批量内容替换
re.split()
- 正则分割
核心功能:
使用正则表达式作为分隔符分割字符串
函数原型:
re.split(pattern, string, maxsplit=0, flags=0)
参数说明:
pattern
:分隔符正则表达式string
:输入字符串maxsplit
:最大分割次数(默认0=全部分割)flags
:正则标志
重要特性:
-
捕获分组保留:如果模式中有捕获分组,分隔符也会包含在结果中
text = "apple,banana;cherry" result = re.split(r'([,;])', text) # 结果: ['apple', ',', 'banana', ';', 'cherry']
-
复杂分隔符:支持多字符分隔符和模式匹配
text = "apple123banana456cherry" result = re.split(r'\d+', text) # 结果: ['apple', 'banana', 'cherry']
-
空匹配处理:开头/结尾的分隔符会产生空字符串
text = ",apple,banana," result = re.split(r',', text) # 结果: ['', 'apple', 'banana', '']
对比
特性 | re.sub() | re.split() |
---|---|---|
主要功能 | 查找并替换 | 按模式分割 |
返回值 | 新字符串 | 字符串列表 |
模式作用 | 匹配要替换的内容 | 作为分隔符 |
特殊功能 | 支持函数替换、反向引用 | 保留捕获分组 |
性能考虑 | 适合批量替换 | 适合复杂分割 |
典型应用 | 数据清洗、文本转换 | 日志解析、数据提取 |
示例
re.sub()
示例:
import re
# 1. 简单替换
text = "The price is $100.00"
clean = re.sub(r'\$', '', text) # 移除美元符号
# 结果: "The price is 100.00"
# 2. 日期格式转换
date = "2023-08-15"
new_date = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', date)
# 结果: "08/15/2023"
# 3. 敏感信息脱敏
email = "contact@example.com"
masked = re.sub(r'(\w{3})[\w.-]+@', r'\1***@', email)
# 结果: "con***@example.com"
# 4. 使用函数进行条件替换
def replacer(match):
num = int(match.group(1))
return f"{num*2}" if num > 50 else match.group(0)
text = "10, 60, 30, 70"
result = re.sub(r'\b(\d+)\b', replacer, text)
# 结果: "10, 120, 30, 140"
re.split()
示例:
import re
# 1. 多分隔符分割
text = "apple,banana;cherry/orange"
result = re.split(r'[,;/]', text)
# 结果: ['apple', 'banana', 'cherry', 'orange']
# 2. 保留分隔符
log = "[ERROR]2023-08-15: File not found"
parts = re.split(r'(\[.*?\])|(\d{4}-\d{2}-\d{2}:)', log)
# 结果: ['', '[ERROR]', None, '2023-08-15:', ' File not found']
# 3. 分割次数控制
text = "1-2-3-4-5"
result = re.split(r'-', text, maxsplit=2)
# 结果: ['1', '2', '3-4-5']
# 4. 复杂分割(单词分割)
text = "camelCaseVariableName"
words = re.split(r'(?<=[a-z])(?=[A-Z])', text)
# 结果: ['camel', 'Case', 'Variable', 'Name']
# 5. 处理连续分隔符
text = "a,,b,,,c"
result = re.split(r',+', text)
# 结果: ['a', 'b', 'c']
第7章:异常处理
1. Bug的由来
-
语法错误(SyntaxError)
- 代码不符合Python语法规则
- 在程序运行前就会被解释器检测到
# 缺少冒号 if True print("Hello")
-
逻辑错误
- 程序能运行但产生错误结果
- 最难发现的错误类型
# 计算阶乘的逻辑错误 def factorial(n): result = 1 for i in range(1, n): # 应该是range(1, n+1) result *= i return result
-
运行时错误(异常)
- 程序执行期间发生的错误
- 通过异常处理机制解决
# 除以零错误 10 / 0 # ZeroDivisionError
2. raise关键字的使用
raise
关键字用于主动触发异常,是控制程序流程的重要工具。
2.1基本用法
# 触发内置异常
if age < 0:
raise ValueError("年龄不能为负数")
# 触发自定义异常
class MyCustomError(Exception):
pass
raise MyCustomError("自定义错误信息")
2.2高级用法
-
重新抛出异常
try: # 可能出错的代码 except SomeException as e: print(f"发生错误: {e}") raise # 重新抛出原始异常
-
转换异常类型
try: # 文件操作 except FileNotFoundError as e: raise RuntimeError("文件处理失败") from e
-
带参数的异常
class InsufficientFundsError(Exception): def __init__(self, balance, amount): super().__init__(f"余额不足: {balance}, 需要: {amount}") self.balance = balance self.amount = amount # 使用 if balance < amount: raise InsufficientFundsError(balance, amount)
3. 常见异常类型
Python内置了丰富的异常类型,以下是常见异常及触发场景:
3.1基础异常
异常类型 | 触发场景 | 示例 |
---|---|---|
SyntaxError | 语法错误 | print("Hello" (缺少括号) |
IndentationError | 缩进错误 | 代码块缩进不一致 |
NameError | 未定义变量 | print(undefined_var) |
TypeError | 类型错误 | "10" + 10 (字符串+数字) |
ValueError | 值错误 | int("abc") |
3.2计算相关异常
异常类型 | 触发场景 | 示例 |
---|---|---|
ZeroDivisionError | 除以零 | 10 / 0 |
OverflowError | 数值溢出 | 10**1000 (在限制环境中) |
ArithmeticError | 所有算术错误的基类 | - |
3.3集合操作异常
异常类型 | 触发场景 | 示例 |
---|---|---|
IndexError | 索引越界 | lst = [1,2]; lst[2] |
KeyError | 键不存在 | d = {'a':1}; d['b'] |
StopIteration | 迭代结束 | next(iter([])) |
3.4 I/O相关异常
异常类型 | 触发场景 | 示例 |
---|---|---|
FileNotFoundError | 文件不存在 | open("nonexist.txt") |
PermissionError | 权限不足 | 写入只读文件 |
IsADirectoryError | 文件操作应用于目录 | open("/directory") |
3.5系统相关异常
异常类型 | 触发场景 | 示例 |
---|---|---|
KeyboardInterrupt | 用户中断(Ctrl+C) | 运行时按下Ctrl+C |
SystemExit | 程序退出 | sys.exit() |
MemoryError | 内存不足 | 分配超大对象 |
3.6其他重要异常
异常类型 | 触发场景 | 示例 |
---|---|---|
AttributeError | 属性不存在 | "".nonexist_method() |
ImportError | 导入失败 | import nonexist_module |
RuntimeError | 一般运行时错误 | 多种情况 |
NotImplementedError | 未实现方法 | 抽象方法中抛出 |
4.完整的异常处理结构
try:
# 可能引发异常的代码
result = 10 / value
except ZeroDivisionError:
# 处理特定异常
print("不能除以零!")
except (TypeError, ValueError) as e:
# 处理多个异常类型
print(f"输入错误: {e}")
except Exception as e:
# 处理所有其他异常
print(f"未知错误: {e}")
# 记录日志
logger.exception("发生异常")
else:
# 没有异常时执行
print(f"计算结果: {result}")
finally:
# 无论是否异常都会执行
print("清理资源...")
5.异常处理原则
-
具体优于宽泛:先捕获具体异常,再捕获通用异常
# 不推荐 try: # ... except Exception: pass # 推荐 try: # ... except FileNotFoundError: # 处理特定情况 except OSError: # 处理更一般的I/O错误
-
避免空except块
# 不推荐 - 隐藏错误 try: risky_operation() except: pass # 推荐 - 至少记录错误 try: risky_operation() except Exception as e: logger.error(f"操作失败: {e}")
-
使用异常链
try: process_file(filename) except FileProcessingError as e: raise ApplicationError("处理失败") from e
-
创建有意义的自定义异常
class PaymentFailedError(Exception): """支付处理失败异常""" def __init__(self, amount, reason): super().__init__(f"支付{amount}失败: {reason}") self.amount = amount self.reason = reason
第8章:函数
函数是 Python 编程的核心构建块,用于组织可重用代码。以下是 Python 函数的完整详解:
1. 函数定义
def greet(name: str) -> str:
"""返回问候语(文档字符串)"""
return f"Hello, {name}!"
def
:定义函数的关键字name: str
:类型提示(参数类型)-> str
:类型提示(返回值类型)"""文档字符串"""
:函数说明(可通过help(greet)
查看)
2. 参数类型
参数类型 | 语法 | 示例 |
---|---|---|
位置参数 | def func(a, b) | func(1, 2) |
默认参数 | def func(a=0) | func() → a=0 |
可变位置参数 | def func(*args) | func(1, 2, 3) → args=(1,2,3) |
可变关键字参数 | def func(**kwargs) | func(x=1, y=2) → kwargs={'x':1, 'y':2} |
仅位置参数 | def func(a, /, b) | func(1, 2) 有效func(a=1, b=2) 无效 |
仅关键字参数 | def func(*, a, b) | func(a=1, b=2) 有效func(1, 2) 无效 |
参数顺序规则:
(位置参数, /, [位置或关键字参数], *args, [关键字参数], **kwargs)
3. 返回值
-
使用
return
返回结果 -
可返回多个值(实际返回元组):
def divide(a, b): quotient = a // b remainder = a % b return quotient, remainder q, r = divide(10, 3) # q=3, r=1
-
无
return
语句时返回None
4. 作用域规则
x = 10 # 全局变量
def modify():
global x # 声明使用全局变量
x = 20 # 修改全局变量
y = 30 # 局部变量
modify()
print(x) # 20
print(y) # NameError: name 'y' is not defined
5. 函数作用
函数可以:
- 赋值给变量
- 作为参数传递
- 作为返回值
- 存储在数据结构中
# 高阶函数示例
def apply_operation(func, a, b):
return func(a, b)
def add(x, y):
return x + y
result = apply_operation(add, 3, 5) # 8
6. Lambda 函数
匿名函数,适用于简单操作:
square = lambda x: x**2
print(square(4)) # 16
# 在排序中使用
points = [(1, 2), (3, 1), (5, 4)]
sorted_points = sorted(points, key=lambda p: p[1]) # 按y坐标排序
7. 闭包(Closures)
函数记住并访问其定义作用域的能力:
def make_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
double = make_multiplier(2)
print(double(5)) # 10
8. 装饰器(Decorators)
修改函数行为的工具:
def log_execution(func):
def wrapper(*args, **kwargs):
print(f"Executing {func.__name__}")
result = func(*args, **kwargs)
print(f"Finished {func.__name__}")
return result
return wrapper
@log_execution
def calculate(a, b):
return a + b * 2
9. 生成器函数
使用 yield
创建迭代器:
def count_up_to(n):
count = 1
while count <= n:
yield count
count += 1
for num in count_up_to(5):
print(num) # 1,2,3,4,5
第九章:面向对象编程
面向对象编程(OOP)是Python的核心编程范式,通过创建对象来组织代码和数据。
1.核心概念
1.1 类与对象
- 类(Class):对象的蓝图/模板
- 对象(Object):类的具体实例
# 定义类
class Dog:
# 类属性 (所有实例共享)
species = "Canis familiaris"
# 构造方法 (初始化对象)
def __init__(self, name, age):
# 实例属性
self.name = name
self.age = age
# 实例方法
def bark(self):
print(f"{self.name} says: Woof!")
# 创建对象
my_dog = Dog("Buddy", 3)
your_dog = Dog("Lucy", 5)
# 访问属性和方法
print(my_dog.name) # 输出: Buddy
my_dog.bark() # 输出: Buddy says: Woof!
print(Dog.species) # 输出: Canis familiaris (类属性)
1.2. 四大支柱
概念 | 描述 | Python实现 |
---|---|---|
封装 | 隐藏内部实现细节 | 私有属性/方法 (__ 前缀) |
继承 | 从父类获得属性和方法 | class Child(Parent): |
多态 | 不同类对象对相同方法的不同实现 | 方法重写 |
抽象 | 定义接口而不实现 | 抽象基类 (ABC) |
2.继承与多态
2.1. 基础继承
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现此方法")
class Cat(Animal):
def speak(self):
return "Meow!"
class Dog(Animal):
def speak(self):
return "Woof!"
# 多态演示
animals = [Cat("Whiskers"), Dog("Buddy")]
for animal in animals:
print(f"{animal.name}: {animal.speak()}")
# 输出:
# Whiskers: Meow!
# Buddy: Woof!
2.2. 多重继承
class Flyable:
def fly(self):
return "Flying high!"
class Swimmable:
def swim(self):
return "Swimming deep!"
class Duck(Flyable, Swimmable):
pass
duck = Duck()
print(duck.fly()) # 输出: Flying high!
print(duck.swim()) # 输出: Swimming deep!
2.3. 方法解析顺序(MRO)
class A:
def show(self):
print("A")
class B(A):
def show(self):
print("B")
class C(A):
def show(self):
print("C")
class D(B, C):
pass
d = D()
d.show() # 输出: B (按照MRO顺序)
print(D.mro())
# 输出: [<class '__main__.D'>, <class '__main__.B'>,
# <class '__main__.C'>, <class '__main__.A'>,
# <class 'object'>]
3.封装与访问控制
访问修饰符
- 公有:默认,可自由访问
- 保护:
_
前缀(约定,非强制) - 私有:
__
前缀(名称修饰)
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner # 公有属性
self._account_number = "123456" # 保护属性
self.__balance = balance # 私有属性
# 公有方法
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"存款成功,余额: {self.__balance}")
def get_balance(self): # 访问私有属性的方法
return self.__balance
account = BankAccount("Alice", 1000)
print(account.owner) # 输出: Alice
print(account._account_number) # 输出: 123456 (但不推荐)
# print(account.__balance) # 错误! AttributeError
print(account.get_balance()) # 输出: 1000 (正确访问方式)
4.特殊方法与运算符重载
方法 | 描述 | 调用时机 |
---|---|---|
__init__(self, ...) | 构造器 | 创建对象时 |
__str__(self) | 字符串表示 | str(obj) 或print(obj) |
__repr__(self) | 正式字符串表示 | repr(obj) |
__len__(self) | 长度 | len(obj) |
__add__(self, other) | 加法 | obj1 + obj2 |
__eq__(self, other) | 相等比较 | obj1 == obj2 |
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __str__(self):
return f"Vector({self.x}, {self.y})"
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2
print(v3) # 输出: Vector(6, 8)
print(v1 == v2) # 输出: False
5.类方法与静态方法
类型 | 装饰器 | 访问权限 | 用途 |
---|---|---|---|
实例方法 | 无 | 访问实例和类 | 常规方法 |
类方法 | @classmethod | 仅访问类 | 替代构造器 |
静态方法 | @staticmethod | 无特殊权限 | 工具函数 |
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
# 类方法 - 替代构造器
@classmethod
def from_string(cls, date_str):
year, month, day = map(int, date_str.split('-'))
return cls(year, month, day)
# 静态方法 - 工具函数
@staticmethod
def is_valid(date_str):
try:
year, month, day = map(int, date_str.split('-'))
return 1 <= month <= 12 and 1 <= day <= 31
except:
return False
# 使用类方法创建对象
d1 = Date.from_string("2023-08-15")
print(d1.year, d1.month, d1.day) # 输出: 2023 8 15
# 使用静态方法
print(Date.is_valid("2023-13-01")) # 输出: False
6.属性装饰器
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""半径属性 (只读)"""
return self._radius
@property
def diameter(self):
"""直径属性 (计算属性)"""
return 2 * self._radius
@diameter.setter
def diameter(self, value):
"""通过直径设置半径"""
self._radius = value / 2
@property
def area(self):
"""面积 (只读计算属性)"""
return 3.14 * self._radius ** 2
c = Circle(5)
print(c.radius) # 输出: 5
print(c.diameter) # 输出: 10
print(c.area) # 输出: 78.5
c.diameter = 14 # 设置直径
print(c.radius) # 输出: 7.0
print(c.area) # 输出: 153.86
# c.area = 100 # 错误! AttributeError (只读属性)
7.抽象基类
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
# 无法实例化抽象类
# s = Shape() # TypeError
# 子类必须实现所有抽象方法
r = Rectangle(4, 5)
print(r.area()) # 输出: 20
print(r.perimeter()) # 输出: 18
第10章:包与模块
1.模块的简介及自定义模块
1.什么是模块?
模块是包含Python定义和语句的.py
文件。它是代码组织的基本单位,允许你将相关的功能分组在一起,提高代码的可重用性和可维护性。
模块的核心价值:
- 代码复用:一次编写,多次使用
- 命名空间管理:避免命名冲突
- 代码组织:逻辑分组,结构清晰
- 性能优化:按需加载,减少内存占用
Python模块类型:
类型 | 描述 | 示例 |
---|---|---|
内置模块 | Python标准库自带 | math , os , sys |
第三方模块 | 社区开发,需额外安装 | numpy , requests |
自定义模块 | 用户自行创建 | my_utils.py |
2.创建自定义模块
创建模块文件
编写一个 .py
文件,例如 my_module.py
:
# my_module.py
# 变量
PI = 3.14159
# 函数
def greet(name):
return f"Hello, {name}!"
# 类
class Calculator:
def add(self, a, b):
return a + b
2.模块的导入
使用自定义模块
在同一目录下创建main.py
:
# 方式1:导入整个模块
import my_module
print(my_module.PI) # 访问模块变量
print(my_module.greet("Alice")) # 调用模块函数
calc = my_module.Calculator() # 创建模块中的类实例
# 方式2:导入特定内容
from my_module import greet, PI
print(PI) # 直接使用变量,无需前缀
print(greet("Bob")) # 直接调用函数
# 方式3:导入所有内容(不推荐,可能导致命名冲突)
from my_module import *
# 方式4:导入时重命名
import my_module as mm
print(mm.PI)
3.Python中的包
在 Python 中,包(Package) 是一种组织模块的高级方式,用于将相关的模块分组管理,避免命名冲突,提高代码的可维护性和复用性。
1.包的基本概念
-
- 什么是包?
- 包是一个包含多个模块的目录,目录中必须包含一个特殊的文
__init__.py
。包可以嵌套,形成层次化的组织结构(类似文件系统的目录树)。
-
- 包的作用
- 模块化组织:将相关模块归类到同一个命名空间下(如 numpy.random、django.db)。
- 避免命名冲突:不同包中的模块可以重名(如 mypackage.utils 和 yourpackage.utils)。
- 简化导入:通过包名直接导入模块,无需关心物理路径。
2.包的结构
基本结构
my_package/
__init__.py # 包的初始化文件(可空)
module1.py # 模块1
module2.py # 模块2
subpackage/ # 子包
__init__.py
submodule.py # 子模块
4.主程序运行
在 Python 中,“主程序运行” 指的是直接执行 Python 脚本(而非作为模块导入)。以下是关键概念和最佳实践:
1. 主程序入口的标准写法
使用 if __name__ == '__main__':
作为程序入口点,确保代码在被直接运行时执行,而被导入时不执行。
def main():
# 主程序逻辑
print("Hello, World!")
if __name__ == '__main__':
main()
2. 关键概念说明
__name__
变量:- 当脚本被直接运行时:
__name__
值为'__main__'
- 当脚本被导入时:
__name__
值为模块名(如'my_module'
)
- 当脚本被直接运行时:
main()
函数:
将主逻辑封装在函数中,提高代码可读性和可重用性
3. 完整示例
# utils.py
def helper():
print("Helper function called")
# main.py
import utils
def config_setup():
print("Initializing configuration...")
def main():
config_setup()
utils.helper()
print("Main program running!")
if __name__ == '__main__':
main()
4. 执行方式
-
直接运行(执行主程序):
python main.py
输出:
Initializing configuration... Helper function called Main program running!
-
作为模块导入(不执行主程序):
# another_script.py import main # 不会触发 main() 的执行
5. 命令行参数处理
使用 argparse
处理命令行参数:
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--input", help="Input file path")
parser.add_argument("--verbose", action="store_true")
args = parser.parse_args()
if args.verbose:
print("Verbose mode enabled")
print(f"Processing file: {args.input}")
if __name__ == '__main__':
main()
运行:
python script.py --input data.txt --verbose
6. 项目结构示例
my_project/
├── main.py
├── config.py
├── utils/
│ ├── __init__.py
│ ├── file_io.py
│ └── logger.py
└── README.md
在 main.py
中:
from config import load_config
from utils.logger import setup_logger
def main():
config = load_config()
logger = setup_logger(config)
logger.info("Program started")
# 主逻辑
if __name__ == '__main__':
main()
遵循这些模式可以创建:
- 可重用的模块化代码
- 支持命令行执行的脚本
- 可被安全导入而不产生副作用的库
- 易于维护的项目结构
5.常用内置模块
以下是 Python 10个最常用内置模块 :
排名 | 模块名 | 核心用途 | 典型使用场景 |
---|---|---|---|
1 | os | 操作系统交互 | 文件/目录操作、路径管理 |
2 | sys | 系统参数控制 | 命令行参数、程序退出 |
3 | datetime | 日期时间处理 | 时间计算、格式化显示 |
4 | json | JSON数据编解码 | API数据处理、配置文件读写 |
5 | re | 正则表达式 | 文本匹配/提取/替换 |
6 | math | 数学运算 | 数值计算、科学计算基础 |
7 | random | 随机数生成 | 抽奖、测试数据生成 |
8 | collections | 增强型数据结构 | 计数器、命名元组、双向队列 |
9 | argparse | 命令行参数解析 | 开发命令行工具 |
10 | logging | 日志记录 | 程序运行监控、错误追踪 |
6.random模块常用函数
函数名 | 描述 | 示例代码及输出 |
---|---|---|
random() | 生成 [0.0, 1.0) 的随机浮点数 | random.random() → 0.3745 |
randint(a, b) | 生成 [a, b] 区间的随机整数 | random.randint(1, 10) → 7 |
uniform(a, b) | 生成 [a, b] 区间的随机浮点数 | random.uniform(2.5, 5.5) → 3.14 |
choice(seq) | 从序列随机选择一个元素 | random.choice(['A','B','C']) → ‘B’ |
shuffle(x) | 将序列随机打乱顺序(原地修改) | lst=[1,2,3]; random.shuffle(lst) → [2,3,1] |
sample(population, k) | 从总体中随机抽取 k 个不重复元素 | random.sample(range(100), 5) → [42, 15, 73, 88, 5] |
randrange(start, stop, step) | 从指定范围随机选择整数 | random.randrange(0, 100, 10) → 30 |
gauss(mu, sigma) | 生成高斯分布随机数(均值为 mu,标准差 sigma) | random.gauss(0, 1) → -0.32 |
seed(a=None) | 初始化随机数生成器 | random.seed(42) 设置随机种子 |
7.time模块常用函数
函数名 | 描述 | 示例代码及输出 |
---|---|---|
time() | 返回当前时间戳(1970年1月1日至今的秒数) | time.time() → 1720628123.456 |
sleep(secs) | 程序暂停执行指定秒数 | time.sleep(2.5) 暂停2.5秒 |
localtime([secs]) | 将时间戳转换为本地时间的结构体 | time.localtime() → tm_year=2024, tm_mon=7, ... |
gmtime([secs]) | 将时间戳转换为UTC时间的结构体 | time.gmtime() → UTC时间结构体 |
strftime(format[, t]) | 将时间结构体格式化为字符串 | time.strftime("%Y-%m-%d %H:%M") → “2024-07-10 14:35” |
strptime(string, format) | 将字符串解析为时间结构体 | time.strptime("2024-07-10", "%Y-%m-%d") → 时间结构体 |
mktime(t) | 将时间结构体转换为时间戳 | t = time.localtime(); time.mktime(t) → 1720628123.0 |
ctime([secs]) | 将时间戳转换为可读字符串 | time.ctime() → “Wed Jul 10 14:35:23 2024” |
perf_counter() | 高精度计时器(用于性能测量) | start=time.perf_counter(); ...; end-start → 0.12345 |
monotonic() | 单调计时器(不受系统时间调整影响) | 用法同perf_counter() ,但精度略低 |
时间格式化符号表(用于strftime
/strptime
)
符号 | 含义 | 示例 |
---|---|---|
%Y | 四位数年份 | 2024 |
%m | 月份(01-12) | 07 |
%d | 日期(01-31) | 10 |
%H | 24小时制小时 | 14 |
%M | 分钟(00-59) | 35 |
%S | 秒(00-59) | 23 |
%A | 完整星期名称 | Wednesday |
%a | 简写星期名称 | Wed |
%B | 完整月份名称 | July |
%b | 简写月份名称 | Jul |
%I | 12小时制小时 | 02 |
%p | AM/PM | PM |
典型使用场景
- 程序计时:
start = time.perf_counter()
# 执行代码...
end = time.perf_counter()
print(f"耗时: {end-start:.4f}秒")
- 倒计时功能:
for i in range(5, 0, -1):
print(f"倒计时: {i}")
time.sleep(1)
- 时间格式转换:
# 字符串 → 时间戳
dt_str = "2024-12-25 08:30"
struct_time = time.strptime(dt_str, "%Y-%m-%d %H:%M")
timestamp = time.mktime(struct_time)
# 时间戳 → 自定义格式
formatted = time.strftime("%Y年%m月%d日 %H时%M分", time.localtime(timestamp))
print(formatted) # 2024年12月25日 08时30分
8.datetime模块中datetime类的使用
1. 基本操作
操作 | 语法 | 示例 | 输出 |
---|---|---|---|
创建对象 | datetime(year, month, day[, hour[, minute[, second[, microsecond]]]) | dt = datetime(2024, 7, 10, 14, 30) | 2024-07-10 14:30:00 |
获取当前时间 | datetime.now() | datetime.now() | 2024-07-10 14:35:22.123456 |
获取UTC时间 | datetime.utcnow() | datetime.utcnow() | 2024-07-10 06:35:22.123456 |
2. 常用属性
dt = datetime(2024, 12, 25, 15, 30, 45)
属性 | 获取值 | 示例 | 输出 |
---|---|---|---|
year | 年份 | dt.year | 2024 |
month | 月份 | dt.month | 12 |
day | 日期 | dt.day | 25 |
hour | 小时 | dt.hour | 15 |
minute | 分钟 | dt.minute | 30 |
second | 秒 | dt.second | 45 |
microsecond | 微秒 | dt.microsecond | 0 |
weekday() | 星期几 (0=周一, 6=周日) | dt.weekday() | 2 (周三) |
isoweekday() | 星期几 (1=周一, 7=周日) | dt.isoweekday() | 3 (周三) |
3. 时间格式化与解析
# 格式化输出
formatted = dt.strftime("%Y-%m-%d %H:%M:%S") # → "2024-12-25 15:30:45"
# 从字符串解析
dt_obj = datetime.strptime("2024-12-25", "%Y-%m-%d")
4. 时间计算(需配合timedelta
)
from datetime import timedelta
# 时间加减
tomorrow = dt + timedelta(days=1)
last_week = dt - timedelta(weeks=1)
# 计算时间差
delta = datetime(2025, 1, 1) - dt
print(delta.days) # 7 (天数差)
print(delta.seconds) # 0 (秒数差)
5. 时间戳转换
# datetime → 时间戳
timestamp = dt.timestamp() # → 1735126245.0
# 时间戳 → datetime
dt_from_ts = datetime.fromtimestamp(1735126245.0)
6. 特殊方法
方法 | 描述 | 示例 |
---|---|---|
date() | 提取日期部分 | dt.date() → date(2024, 12, 25) |
time() | 提取时间部分 | dt.time() → time(15, 30, 45) |
combine() | 合并date和time | datetime.combine(date(2024,12,25), time(15,30)) |
replace() | 替换部分值 | dt.replace(year=2025, hour=10) → 2025-12-25 10:30:45 |
7. 示例
from datetime import datetime, timedelta
# 创建特定日期
christmas = datetime(2024, 12, 25, 15, 30)
# 计算时间差
now = datetime.now()
days_left = (christmas - now).days
# 格式化输出
print(f"距离2024年圣诞节还有 {days_left} 天")
print(f"具体时间: {christmas.strftime('%Y年%m月%d日 %A %H:%M')}")
# 时间计算
new_year = christmas + timedelta(days=7)
print(f"新年日期: {new_year.date()}")
8. 常用格式化符号
符号 | 含义 | 示例输出 |
---|---|---|
%Y | 四位数年份 | 2024 |
%m | 两位数月份 | 12 |
%d | 两位数日期 | 25 |
%H | 24小时制小时 | 15 |
%M | 分钟 | 30 |
%S | 秒 | 45 |
%f | 微秒 | 000000 |
%A | 星期全名 | Wednesday |
%a | 星期缩写 | Wed |
%B | 月份全名 | December |
%b | 月份缩写 | Dec |
9.timedelta类的使用
timedelta
是 Python datetime
模块中用于表示时间间隔或时间差的类。以下是核心用法总结:
1.创建 timedelta
对象
1.1构造函数参数
from datetime import timedelta
# 主要参数(均为可选,默认为0)
delta = timedelta(
days=0, # 天数
seconds=0, # 秒数
microseconds=0, # 微秒数
milliseconds=0, # 毫秒数(转换为微秒)
minutes=0, # 分钟数(转换为秒)
hours=0, # 小时数(转换为秒)
weeks=0 # 周数(转换为天)
)
1.2创建示例
# 1天时间差
one_day = timedelta(days=1)
# 2小时30分钟
two_hours_thirty = timedelta(hours=2, minutes=30)
# 1周半
one_and_half_week = timedelta(weeks=1.5)
# 90秒
ninety_seconds = timedelta(seconds=90)
2.核心属性和方法
属性/方法 | 描述 | 示例 |
---|---|---|
.days | 天数部分(可为负数) | timedelta(days=5).days → 5 |
.seconds | 秒数部分(0-86399) | timedelta(hours=2).seconds → 7200 |
.microseconds | 微秒部分 | timedelta(microseconds=500).microseconds → 500 |
.total_seconds() | 返回总秒数(浮点数) | timedelta(hours=1).total_seconds() → 3600.0 |
3.时间计算操作
3.1. 与 datetime
对象运算
from datetime import datetime
now = datetime.now()
# 未来时间
future = now + timedelta(days=7)
# 过去时间
past = now - timedelta(hours=48)
3.2. 两个 datetime
对象相减
start = datetime(2024, 1, 1)
end = datetime(2024, 1, 10)
duration = end - start # 返回 timedelta 对象
print(duration.days) # 输出: 9
3.3. timedelta
之间的运算
delta1 = timedelta(days=3)
delta2 = timedelta(hours=12)
# 加法
combined = delta1 + delta2 # 3天12小时
# 减法
difference = delta1 - delta2 # 2天12小时
# 乘法
doubled = delta1 * 2 # 6天
# 除法
half = delta1 / 2 # 1天12小时
ratio = delta1 / delta2 # 6.0 (浮点数)
4.实际应用场景
4.1. 计算到期日期
purchase_date = datetime(2024, 7, 10)
warranty_period = timedelta(days=365)
expiry_date = purchase_date + warranty_period
4.2. 倒计时计算
new_year = datetime(2025, 1, 1)
now = datetime.now()
time_left = new_year - now
print(f"距离2025年还有:")
print(f"{time_left.days} 天")
print(f"{time_left.seconds // 3600} 小时")
4.3. 工作日计算
def add_workdays(start_date, days):
current = start_date
while days > 0:
current += timedelta(days=1)
# 周一至周五是工作日 (0=周一, 6=周日)
if current.weekday() < 5:
days -= 1
return current
4.4. 时间区间生成器
def time_range(start, end, delta):
current = start
while current < end:
yield current
current += delta
# 每15分钟生成一个时间点
for dt in time_range(datetime(2024,7,10,9), datetime(2024,7,10,17), timedelta(minutes=15)):
print(dt.strftime("%H:%M"))
5.注意事项
-
最大范围:
timedelta
支持的最大天数约为 999999999(约273万年级别) -
负数处理:
negative_delta = timedelta(days=-5) print(negative_delta.days) # 输出: -5
-
精度限制:
- 最小单位为微秒(1微秒 = 10⁻⁶秒)
- 毫秒会被转换为微秒(1毫秒 = 1000微秒)
-
月份/年处理:
timedelta
不支持直接添加月份或年份(月份天数不固定),需使用第三方库:# 使用 dateutil.relativedelta from dateutil.relativedelta import relativedelta future = now + relativedelta(months=2)
6.完整示例:项目时间线计算
from datetime import datetime, timedelta
# 项目开始日期
start_date = datetime(2024, 9, 1)
# 各阶段时间分配
phases = {
"设计": timedelta(days=14),
"开发": timedelta(days=45),
"测试": timedelta(days=21),
"部署": timedelta(days=7)
}
# 计算各阶段时间线
current_date = start_date
timeline = {}
for phase, duration in phases.items():
end_date = current_date + duration
timeline[phase] = (current_date, end_date)
current_date = end_date # 下一阶段开始时间
# 打印时间线
print("项目时间线:")
for phase, (start, end) in timeline.items():
print(f"- {phase}: {start.strftime('%Y-%m-%d')} 至 {end.strftime('%Y-%m-%d')}")
# 计算总时长
total_duration = sum(phases.values(), timedelta())
print(f"\n项目总时长: {total_duration.days} 天")
输出示例:
项目时间线:
- 设计: 2024-09-01 至 2024-09-15
- 开发: 2024-09-15 至 2024-10-30
- 测试: 2024-10-30 至 2024-11-20
- 部署: 2024-11-20 至 2024-11-27
项目总时长: 87 天
10.第三方模块的安装与卸载
1.安装第三方模块
1. 使用 pip (Python 包管理器)
# 基本安装
pip install package_name
# 安装特定版本
pip install package_name==1.2.3
# 从requirements.txt安装
pip install -r requirements.txt
# 安装预发布版
pip install --pre package_name
# 安装本地包
pip install ./downloads/package_name-1.2.3.tar.gz
2. 使用 conda (Anaconda/Miniconda 包管理器)
# 基本安装
conda install package_name
# 指定安装通道
conda install -c conda-forge package_name
# 创建环境并安装
conda create -n myenv python=3.10 package_name
3. 其他安装方式
- 源码安装:
python setup.py install
- 直接安装GitHub仓库:
pip install git+https://github.com/user/repo.git
2.升级第三方模块
1. 升级单个包
pip install --upgrade package_name
2. 升级所有包
# 生成当前包列表
pip freeze > requirements.txt
# 编辑requirements.txt将所有==改为>=
# 重新安装所有包
pip install -r requirements.txt --upgrade
3. 使用 pip-review
# 安装工具
pip install pip-review
# 查看可升级包
pip-review
# 自动升级所有包
pip-review --auto
3.卸载第三方模块
3.1. 基本卸载
pip uninstall package_name
3.2. 卸载多个包
pip uninstall package1 package2 package3
3.3. 根据requirements.txt卸载
pip uninstall -r requirements.txt -y
3.4. 强制卸载(忽略依赖检查)
pip uninstall package_name --break-system-packages
4.查看已安装模块
1. 列出所有包
pip list
2. 检查过期包
pip list --outdated
3. 显示包详情
pip show package_name
4. 导出requirements.txt
pip freeze > requirements.txt
11.requests模块的使用
第11章:文件操作
1.文件的概述及基本操作步骤
- 本质:通过Python内置函数与文件对象交互(读/写/修改)
- 关键函数:
open()
创建文件对象 - 核心模式:指定文件访问模式(读
r
、写w
、追加a
等)
基本操作步骤
1. 打开文件
file = open("文件名.txt", "模式") # 例如:open("data.txt", "r")
常用模式:
模式 | 说明 | 文件存在 | 文件不存在 |
---|---|---|---|
r | 读取(默认) | 正常打开 | 报错 |
w | 写入 | 清空 | 新建 |
a | 追加写入 | 保留内容 | 新建 |
x | 独占创建 | 报错 | 新建 |
b | 二进制模式 | 例: rb | |
+ | 读写模式 | 例: r+ |
2. 读取文件
# 读取整个文件
content = file.read()
# 逐行读取
for line in file:
print(line.strip()) # .strip() 去除换行符
# 读取单行
first_line = file.readline()
3. 写入文件
# 写入字符串(覆盖/新建)
file.write("Hello Python!\n")
# 写入多行(需列表格式)
lines = ["Line1\n", "Line2\n"]
file.writelines(lines)
4. 关闭文件
file.close() # 释放系统资源
2.文件的写入操作
2.1 基本写入操作
open()
方法
open()
函数常用形式是接收两个参数:文件名(file)和模式(mode)。
open(file, mode='r')
完整的语法格式为:
参数说明
- file: 必需,文件路径(相对或者绝对路径)。
- mode: 可选,文件打开模式
- buffering: 设置缓冲
- encoding: 一般使用utf8
- errors: 报错级别
- newline: 区分换行符
- closefd: 传入的file参数类型
- opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
下面是一个示例:
# 1. 打开文件('w'模式会覆盖原有内容)
fp = open("data.txt", "w",encoding="utf-8")
# 2. 写入单行内容
fp.write("第一行内容\n") # \n 表示换行符
# 3. 写入多行内容
lines = ["第二行\n", "第三行\n"]
fp.writelines(lines) # 接收字符串列表
fp.close()
3.文件的读取操作及文件复制
3.1基础文件读取操作
# 1. 打开文件
file = open("data.txt", "r") # 不指定编码,使用系统默认
# 2. 读取整个文件内容
content = file.read()
print("文件内容:")
print(content)
# 3. 关闭文件
file.close()
3.2逐行读取文件
# 打开文件
file = open("data.txt", "r")
# 逐行读取并打印
print("\n逐行内容:")
line = file.readline()
while line:
print(line.strip()) # 移除换行符
line = file.readline()
# 关闭文件
file.close()
3.3文件复制操作
# 1. 打开源文件和目标文件
source = open("original.txt", "rb") # 二进制模式读取
destination = open("copy.txt", "wb") # 二进制模式写入
# 2. 复制文件内容
destination.write(source.read()) # 一次性读取并写入
# 3. 关闭文件
source.close()
destination.close()
3.4最简文件读取模板
# 三步操作:打开 → 读取 → 关闭
f = open("file.txt", "r")
data = f.read()
f.close()
4.with语句的使用
4.1基本语法
with open(文件路径, 模式) as 文件对象:
# 在此代码块中使用文件对象
# ...
# 退出代码块后文件自动关闭
4.2优势
- 自动资源管理:确保文件正确关闭(即使发生异常)
- 代码简洁:减少样板代码(无需显式调用
.close()
) - 异常安全:在发生异常时仍能正确关闭文件
- 可读性强:清晰界定文件操作范围
4.3基础文件操作示例
4.3.1文件读取
with open("data.txt", "r", encoding="utf-8") as file:
content = file.read()
print(f"文件内容:\n{content}")
# 此处文件已自动关闭
4.3.2文件写入
with open("output.txt", "w") as file:
file.write("第一行内容\n")
file.write("第二行内容\n")
# 文件已关闭且内容已写入磁盘
4.3.3文件追加
with open("log.txt", "a") as log_file:
log_file.write(f"[{time.ctime()}] 系统启动\n")
5.一维数据和二维数据的存储与读取
在Python中处理数据时,一维数据(如列表、元组)和二维数据(如矩阵、表格)的存储与读取有不同方法。
5.1一维数据的存储与读取
5.1.1. 文本文件存储
# 存储
data_1d = [1, 2, 3, 4, 5]
with open("data_1d.txt", "w") as f:
# 用逗号分隔
f.write(",".join(map(str, data_1d)))
# 或用换行符分隔
# for item in data_1d:
# f.write(f"{item}\n")
5.1.2. 文本文件读取
# 方法1:读取后分割
with open("data_1d.txt", "r") as f:
content = f.read()
data = [int(x) for x in content.split(",")] # 转换为整数列表
print("一维数据:", data)
# 方法2:逐行读取
# with open("data_1d.txt", "r") as f:
# data = [int(line.strip()) for line in f]
5.1.3. JSON格式存储(推荐)
import json
data_1d = ["苹果", "香蕉", "橙子"]
# 存储
with open("fruits.json", "w", encoding="utf-8") as f:
json.dump(data_1d, f, ensure_ascii=False) # 支持中文
# 读取
with open("fruits.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print("水果列表:", loaded_data)
5.2二维数据的存储与读取
5.2.1. CSV格式
import csv
# 二维数据示例
data_2d = [
["姓名", "年龄", "城市"],
["张三", 25, "北京"],
["李四", 30, "上海"],
["王五", 28, "广州"]
]
# 存储CSV
with open("people.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(data_2d) # 写入所有行
# 读取CSV
with open("people.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
table_data = [row for row in reader]
print("二维表格数据:")
for row in table_data:
print(row)
5.2.2. 文本格式存储
# 存储
with open("matrix.txt", "w") as f:
for row in data_2d:
# 每行用制表符分隔
f.write("\t".join(map(str, row)) + "\n")
# 读取
matrix = []
with open("matrix.txt", "r") as f:
for line in f:
# 分割每行并转换类型
row = [int(x) if x.isdigit() else x for x in line.strip().split("\t")]
matrix.append(row)
5.2.3. JSON格式存储
# 存储
with open("data_2d.json", "w") as f:
json.dump(data_2d, f)
# 读取
with open("data_2d.json", "r") as f:
loaded_2d = json.load(f)
6.高维数据的存储和读取
7.os模块中常中的函数
os
模块是 Python 与操作系统交互的核心模块,提供了丰富的文件和目录操作功能。
7.1目录操作
1. 目录遍历与列表
import os
# 列出当前目录所有内容(文件和子目录)
print(os.listdir()) # 等同于 os.listdir('.')
# 递归遍历目录(返回生成器)
for root, dirs, files in os.walk('.'):
print(f"当前目录: {root}")
print(f"子目录: {dirs}")
print(f"文件: {files}\n")
2. 目录创建与删除
# 创建单个目录
os.mkdir('new_dir')
# 递归创建多级目录
os.makedirs('parent/child/grandchild', exist_ok=True) # exist_ok避免已存在时报错
# 删除空目录
os.rmdir('empty_dir')
# 递归删除目录树(慎用!)
import shutil
shutil.rmtree('directory_to_remove') # 注意:在os模块中,实际属于shutil
3. 目录路径操作
# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前目录: {current_dir}")
# 切换工作目录
os.chdir('/path/to/new/directory')
# 获取用户主目录
home_dir = os.path.expanduser('~')
print(f"用户主目录: {home_dir}")
7.2文件操作
1. 文件管理
# 重命名文件/目录
os.rename('old.txt', 'new.txt')
# 删除文件
os.remove('file_to_delete.txt')
# 复制文件(使用shutil)
shutil.copy('source.txt', 'destination.txt')
# 获取文件大小(字节)
size = os.path.getsize('document.pdf')
print(f"文件大小: {size} 字节")
2. 文件路径操作
# 拼接路径(跨平台安全)
full_path = os.path.join('dir', 'subdir', 'file.txt')
# 获取绝对路径
abs_path = os.path.abspath('relative/path')
# 标准化路径(处理../等)
normalized = os.path.normpath('dir/../subdir/./file.txt')
# 分割路径
dirname, filename = os.path.split('/path/to/file.txt')
print(f"目录: {dirname}, 文件名: {filename}")
# 分割文件名与扩展名
name, ext = os.path.splitext('image.jpg')
print(f"文件名: {name}, 扩展名: {ext}")
7.3路径判断与信息
1. 路径存在性检查
# 检查路径是否存在
print(os.path.exists('/some/path')) # True/False
# 检查是否为文件
print(os.path.isfile('document.txt')) # True/False
# 检查是否为目录
print(os.path.isdir('some_directory')) # True/False
# 检查是否为符号链接
print(os.path.islink('symlink_file'))
2. 路径信息获取
# 获取最后访问时间(时间戳)
access_time = os.path.getatime('file.txt')
# 获取最后修改时间
modify_time = os.path.getmtime('file.txt')
# 获取创建时间(Windows)
creation_time = os.path.getctime('file.txt')
7.4系统信息与操作
1. 系统信息
# 获取操作系统名称
print(os.name) # 'posix' (Linux/Mac) 或 'nt' (Windows)
# 获取环境变量
print(os.environ['PATH'])
# 获取特定环境变量
home = os.getenv('HOME') # 或 os.environ.get('HOME')
2. 系统命令执行
# 执行系统命令(阻塞式)
os.system('ls -l') # Linux/Mac
os.system('dir') # Windows
# 启动文件(使用关联程序)
os.startfile('document.pdf') # Windows特有
7.5os模块函数速查表
类别 | 函数 | 描述 |
---|---|---|
路径操作 | os.path.join() | 安全拼接路径 |
os.path.abspath() | 获取绝对路径 | |
os.path.dirname() | 获取目录部分 | |
os.path.basename() | 获取文件名部分 | |
文件操作 | os.rename() | 重命名文件/目录 |
os.remove() | 删除文件 | |
os.stat() | 获取文件状态 | |
目录操作 | os.listdir() | 列出目录内容 |
os.mkdir() | 创建目录 | |
os.makedirs() | 递归创建目录 | |
os.rmdir() | 删除空目录 | |
系统信息 | os.name | 操作系统名称 |
os.getcwd() | 当前工作目录 | |
os.environ | 环境变量字典 | |
进程管理 | os.system() | 执行系统命令 |
os.startfile() | 用关联程序打开文件 |
第12章:程序与进程
1. 函数式创建子进程
使用multiprocessing.Process
类创建子进程:
from multiprocessing import Process
import os
def task(name):
print(f"子进程 {name} 执行中, PID={os.getpid()}")
if __name__ == '__main__':
# 创建子进程
p = Process(target=task, args=('worker',))
p.start() # 启动子进程
p.join() # 等待子进程结束
print("子进程执行完毕")
2. Process类中常用的属性和方法
属性/方法 | 说明 |
---|---|
start() | 启动子进程 |
join([timeout]) | 等待子进程结束 |
is_alive() | 检查进程是否在运行 |
name | 进程名称 |
pid | 进程ID |
daemon | 是否为守护进程 |
terminate() | 终止进程 |
3. 继承式创建子进程
通过继承Process
类创建子进程:
from multiprocessing import Process
class MyProcess(Process):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print(f"自定义进程 {self.name} 执行")
if __name__ == '__main__':
p = MyProcess('worker')
p.start()
p.join()
4. 进程池的使用
使用Pool
管理多个进程:
from multiprocessing import Pool
def square(x):
return x * x
if __name__ == '__main__':
with Pool(4) as pool: # 创建4个进程的池
results = pool.map(square, range(10))
print(results) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
5. 并发和并行的概念
概念 | 说明 |
---|---|
并发 | 多个任务交替执行(单核CPU) |
并行 | 多个任务同时执行(多核CPU) |
6. 进程之间数据是否共享
- 默认不共享数据:每个进程有自己的内存空间
- 需要共享数据时:使用队列(Queue)、管道(Pipe)或共享内存
7. 队列的基本使用
Queue
用于进程间安全数据传输:
from multiprocessing import Queue
q = Queue(3) # 创建容量为3的队列
q.put('A') # 放入数据
q.put('B')
print(q.get()) # 获取数据: 'A'
print(q.qsize()) # 当前队列大小: 1
8. 使用队列实现进程之间的通信
from multiprocessing import Process, Queue
def producer(q):
q.put('Hello from producer')
def consumer(q):
print('收到:', q.get())
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer, args=(q,))
p2 = Process(target=consumer, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
9. 函数式创建线程
使用threading.Thread
创建线程:
import threading
def task():
print("线程执行中")
t = threading.Thread(target=task)
t.start()
t.join()
10. 继承式创建线程
通过继承Thread
类创建线程:
import threading
class MyThread(threading.Thread):
def run(self):
print("自定义线程执行")
t = MyThread()
t.start()
t.join()