# 目录
- 字符串
1.1 字符串的创建与基本特性
1.2 字符串的索引与切片
1.3 字符串的内置处理函数
1.4 字符串的常用方法
1.5 字符串的格式化
1.6 字符串的连接与重复
1.7 字符串的成员关系判断 - 数据类型转换
2.1 基本数据类型转换
2.2 高级数据类型转换
2.3 常用数学函数 - 列表
3.1 列表的创建
3.2 列表的访问
3.3 列表的遍历
3.4 列表元素的增加
3.5 列表元素的删除
3.6 列表元素的修改
3.7 列表元素的排序
3.8 列表的其他操作 - 元组
4.1 元组的基本特性
4.2 元组的常用操作
4.3 序列解包 - 字典
5.1 字典的基本特性
5.2 字典的创建
5.3 字典元素的访问
5.4 字典元素的修改
5.5 字典的遍历 - 集合
6.1 集合的基本特性
6.2 集合的创建
6.3 集合的常用方法及运算符
6.4 不可变集合 - 函数
7.1 内置函数
7.2 自定义函数
7.3 函数的特殊参数
7.4 lambda 函数
7.5 变量作用域
7.6 递归函数
7.7 main 函数 - 面向对象程序设计
8.1 类与对象
8.2 属性
8.3 方法
8.4 运算符重载
8.5 继承
8.6 多态性 - 文件和目录操作
9.1 文件类型与基本操作
9.2 文件打开模式
9.3 文件读写方法
9.4 CSV 文件操作
9.5 Excel 文件操作
9.6 图像文件操作
9.7 JSON 文件操作
9.8 os 和 os.path 模块
9.9 shutil 模块 - 异常处理
10.1 异常类
10.2 异常处理结构
10.3 抛出异常
10.4 自定义异常
10.5 断言 - 常用库
11.1 库的导入方式
11.2 math 库
11.3 random 库
11.4 datetime 库
11.5 NumPy 库
11.6 pandas 库
11.7 matplotlib 库
# 1. 字符串
# 1.1 字符串的创建与基本特性
# 创建方式
| |
| s1 = 'Hello' |
| |
| s2 = "World" |
| |
| s3 = '''Hello |
| World''' |
| s4 = """Hello |
| World""" |
# 基本特性
- 不可变性:字符串创建后不可修改,任何修改操作都会返回新字符串
- 有序性:支持索引和切片操作
- 大小写敏感:
'A' != 'a'
# 易错点
- 单引号字符串内可以包含双引号,双引号字符串内可以包含单引号
- 若字符串内需要包含相同引号,需使用转义字符
\ - 三引号字符串会保留所有格式,包括换行符和缩进
# 1.2 字符串的索引与切片
# 索引
| s = "Python" |
| print(s[0]) |
| print(s[-1]) |
# 切片
| s = "Python" |
| print(s[0:3]) |
| print(s[:3]) |
| print(s[3:]) |
| print(s[0:6:2]) |
| print(s[::-1]) |
# 注意点
- 切片不会引发索引越界异常
- 切片结果不包含结束索引位置的字符
- 步长可以为负数,表示从右向左取值
# 1.3 字符串的内置处理函数
| 函数 | 说明 | 示例 |
|---|
str(obj) | 将对象转换为字符串 | str(123) → '123' |
len(s) | 返回字符串长度 | len('Python') → 6 |
# 1.4 字符串的常用方法
# 1.4.1 split () - 分割字符串
| s = "Hello,World,Python" |
| print(s.split(',')) |
| print(s.split(',', 1)) |
# 1.4.2 join () - 连接字符串
| lst = ['Hello', 'World', 'Python'] |
| print(','.join(lst)) |
# 1.4.3 replace () - 替换字符串
| s = "Hello World" |
| print(s.replace('World', 'Python')) |
| print(s.replace('o', '0', 1)) |
# 1.4.4 strip () /lstrip () /rstrip () - 去除空白字符
| s = " Hello World " |
| print(s.strip()) |
| print(s.lstrip()) |
| print(s.rstrip()) |
| |
| |
| s = "###Hello World###" |
| print(s.strip('#')) |
# 1.4.5 其他常用方法
| s = "Hello World" |
| print(s.upper()) |
| print(s.lower()) |
| print(s.find('o')) |
| print(s.rfind('o')) |
| print(s.startswith('Hello')) |
| print(s.endswith('World')) |
# 1.5 字符串的格式化
| |
| print("Hello, {0}! I'm {1}.".format("World", "Python")) |
| |
| print("Hello, {name}! I'm {lang}.".format(name="World", lang="Python")) |
| |
| print("Pi is approximately {:.2f}".format(3.14159)) |
| print("Number: {:05d}".format(123)) |
| print("Percent: {:.1%}".format(0.75)) |
# 1.5.2 f-string(Python 3.6+)
| name = "World" |
| lang = "Python" |
| print(f"Hello, {name}! I'm {lang}.") |
| pi = 3.14159 |
| print(f"Pi is approximately {pi:.2f}") |
# 1.5.3 老式格式化(% 运算符)
| print("Hello, %s! I'm %s." % ("World", "Python")) |
| print("Pi is approximately %.2f" % 3.14159) |
# 注意点
- 推荐使用 f-string,语法更简洁,性能更好
- format () 方法更灵活,支持位置参数、关键字参数等
- 老式格式化(%)在 Python 3 中仍支持,但不推荐使用
# 1.6 字符串的连接与重复
| |
| print("Hello" + " " + "World") |
| |
| print("Hello" * 3) |
# 1.7 字符串的成员关系判断
| s = "Hello World" |
| print('Hello' in s) |
| print('Python' in s) |
| print('Hello' not in s) |
# 1.8 字符串小结
- 字符串是不可变的有序序列
- 支持索引和切片操作
- 提供丰富的内置方法处理字符串
- 多种格式化方式,推荐使用 f-string
# 2. 数据类型转换
# 2.1 基本数据类型转换
| |
| print(int(3.14)) |
| print(int("123")) |
| print(int("0x10", 16)) |
| |
| |
| print(float(3)) |
| print(float("3.14")) |
| |
| |
| print(bool(0)) |
| print(bool(1)) |
| print(bool("")) |
| print(bool("Hello")) |
# 注意点
int() 转换小数时会截断小数部分,不是四舍五入- 字符串转数字时,字符串必须是有效的数字表示
- 空字符串、0、None 转换为布尔值都是 False,其他值为 True
# 2.2 高级数据类型转换
| |
| print(complex(1)) |
| print(complex(1, 2)) |
| |
| |
| print(str(123)) |
| print(str([1, 2, 3])) |
| |
| |
| print(repr('Hello')) |
| |
| |
| print(eval('1 + 2')) |
| print(eval('"Hello" + "World"')) |
| |
| |
| print(chr(65)) |
| |
| |
| print(ord('A')) |
| |
| |
| print(hex(16)) |
| |
| |
| print(oct(8)) |
# 注意点
eval() 函数会执行字符串中的任意代码,存在安全风险,不要用于处理用户输入repr() 和 str() 的区别: repr() 返回对象的 “官方” 字符串表示,适合调试; str() 返回对象的 “友好” 字符串表示,适合用户查看
# 2.3 常用数学函数
| import math |
| |
| |
| print(abs(-10)) |
| print(min(1, 2, 3)) |
| print(max(1, 2, 3)) |
| print(math.sqrt(16)) |
| print(math.ceil(3.14)) |
| print(math.floor(3.14)) |
| |
| |
| s = "Hello World" |
| print(len(s)) |
| print(s.upper()) |
| print(s.lower()) |
| print(s.find('o')) |
| print(s.replace('o', '0')) |
| print(s.strip()) |
# 2.4 数据类型转换小结
- Python 提供丰富的数据类型转换函数
- 转换过程中需注意数据类型的兼容性
- 高级转换函数(如 eval ())存在安全风险,需谨慎使用
# 3. 列表
# 3.1 列表的创建
# 3.1.1 定义法
| lst1 = [1, 2, 3] |
| lst2 = [1, 'a', True, [1, 2]] |
# 3.1.2 list () 函数
| lst1 = list() |
| lst2 = list("Python") |
| lst3 = list((1, 2, 3)) |
# 3.1.3 列表生成式
| |
| lst1 = [x for x in range(5)] |
| |
| |
| lst2 = [x for x in range(10) if x % 2 == 0] |
| |
| |
| lst3 = [x + y for x in 'AB' for y in '12'] |
# 3.2 列表的访问
| lst = [1, 2, 3, 4, 5] |
| print(lst[0]) |
| print(lst[-1]) |
| print(lst[1:4]) |
# 注意点
- 索引越界会引发 IndexError 异常
- 切片不会引发索引越界异常
# 3.3 列表的遍历
# 3.3.1 for 循环
| lst = [1, 2, 3, 4, 5] |
| for item in lst: |
| print(item) |
# 3.3.2 for 循环配合 enumerate () 函数
| lst = ['a', 'b', 'c'] |
| for index, item in enumerate(lst): |
| print(index, item) |
| |
| |
| |
| |
# 3.3.3 while 循环
| lst = [1, 2, 3, 4, 5] |
| i = 0 |
| while i < len(lst): |
| print(lst[i]) |
| i += 1 |
# 3.4 列表元素的增加
# 3.4.1 append () - 在列表末尾添加元素
| lst = [1, 2, 3] |
| lst.append(4) |
| print(lst) |
# 3.4.2 extend () - 在列表末尾添加另一个列表的所有元素
| lst1 = [1, 2, 3] |
| lst2 = [4, 5, 6] |
| lst1.extend(lst2) |
| print(lst1) |
# 3.4.3 insert () - 在指定位置插入元素
| lst = [1, 2, 3] |
| lst.insert(1, 'a') |
| print(lst) |
# 注意点
append() 只能添加一个元素,即使添加的是列表,也会作为单个元素添加extend() 添加的是列表的所有元素,不是作为单个元素insert() 的时间复杂度为 O (n),频繁在列表开头插入元素会影响性能
# 3.5 列表元素的删除
# 3.5.1 del 命令
| lst = [1, 2, 3, 4, 5] |
| del lst[0] |
| print(lst) |
| del lst[1:3] |
| print(lst) |
# 3.5.2 pop () 方法
| lst = [1, 2, 3, 4, 5] |
| print(lst.pop()) |
| print(lst) |
| print(lst.pop(1)) |
| print(lst) |
# 3.5.3 remove () 方法
| lst = [1, 2, 3, 2, 4] |
| lst.remove(2) |
| print(lst) |
# 3.5.4 clear () 方法
| lst = [1, 2, 3, 4, 5] |
| lst.clear() |
| print(lst) |
# 注意点
del 命令可以删除单个元素或切片pop() 方法有返回值, remove() 方法没有返回值remove() 方法删除第一个匹配的元素,若元素不存在会引发 ValueError 异常
# 3.6 列表元素的修改
| lst = [1, 2, 3, 4, 5] |
| lst[0] = 'a' |
| print(lst) |
| lst[1:3] = [6, 7] |
| print(lst) |
# 3.7 列表元素的排序
# 3.7.1 sort () 方法 - 原地排序
| lst = [3, 1, 4, 1, 5, 9] |
| lst.sort() |
| print(lst) |
| lst.sort(reverse=True) |
| print(lst) |
# 3.7.2 sorted () 函数 - 返回新列表
| lst = [3, 1, 4, 1, 5, 9] |
| sorted_lst = sorted(lst) |
| print(sorted_lst) |
| print(lst) |
# 注意点
sort() 方法原地排序,修改原列表,无返回值sorted() 函数返回新列表,原列表不变- 都支持
reverse 参数控制排序方向 - 都支持
key 参数指定排序依据
# 3.8 列表的其他操作
| lst = [1, 2, 3, 4, 5] |
| print(len(lst)) |
| print(lst.count(1)) |
| print(lst.index(3)) |
| print(sum(lst)) |
| print(min(lst)) |
| print(max(lst)) |
| print(lst.copy()) |
| lst.reverse() |
| print(lst) |
# 3.9 列表小结
- 列表是可变的有序序列
- 元素可以是任何类型,支持不同类型的元素
- 提供丰富的方法操作列表
- 支持切片、索引等操作
# 4. 元组
# 4.1 元组的基本特性
- 有序性:支持索引和切片操作
- 不可变性:创建后不可修改
- 元素类型多样性:元素可以是任何类型
# 4.2 元组的常用操作
# 创建
| |
| t1 = (1, 2, 3) |
| |
| t2 = 1, 2, 3 |
| |
| t3 = (1,) |
| |
| t4 = tuple([1, 2, 3]) |
# 访问
| t = (1, 2, 3, 4, 5) |
| print(t[0]) |
| print(t[1:4]) |
# 其他操作
| t = (1, 2, 3, 4, 5) |
| print(len(t)) |
| print(t.count(1)) |
| print(t.index(3)) |
| print(sum(t)) |
| print(min(t)) |
| print(max(t)) |
# 注意点
- 创建单个元素的元组时,必须在元素后面加逗号,否则会被视为普通括号
- 元组是不可变的,但如果元组中包含可变对象(如列表),则可变对象的内容可以修改
# 4.3 序列解包
| |
| t = (1, 2, 3) |
| a, b, c = t |
| print(a, b, c) |
| |
| |
| t = (1, 2, 3, 4, 5) |
| a, b, *rest = t |
| print(a, b, rest) |
| |
| |
| a, b = 1, 2 |
| a, b = b, a |
| print(a, b) |
# 注意点
- 解包时变量数量必须与元组长度匹配,否则会引发 ValueError 异常
- 扩展解包(*rest)可以接收任意数量的元素,返回列表
- 序列解包适用于所有序列类型(列表、元组、字符串等)
# 4.4 元组小结
- 元组是不可变的有序序列
- 适合存储不可变的数据集合
- 支持序列解包,方便变量赋值
# 5. 字典
# 5.1 字典的基本特性
- 键值对存储:键必须唯一,值可以是任何类型
- 键的要求:键必须是不可变类型(数字、字符串、元组)
- 可变容器:创建后可以修改
- 无序性:Python 3.7 + 中字典保持插入顺序,之前版本无序
# 5.2 字典的创建
# 5.2.1 使用花括号直接创建
| d1 = {'name': 'Tom', 'age': 18} |
| d2 = {} |
# 5.2.2 利用 dict 函数生成字典
| |
| d1 = dict() |
| |
| d2 = dict([('name', 'Tom'), ('age', 18)]) |
| |
| d3 = dict(zip(['name', 'age'], ['Tom', 18])) |
| |
| d4 = dict(name='Tom', age=18) |
# 5.3 字典元素的访问
# 5.3.1 使用方括号
| d = {'name': 'Tom', 'age': 18} |
| print(d['name']) |
| print(d['gender']) |
# 5.3.2 get () 方法
| d = {'name': 'Tom', 'age': 18} |
| print(d.get('name')) |
| print(d.get('gender')) |
| print(d.get('gender', 'Unknown')) |
# 5.4 字典元素的修改
# 5.4.1 增加新元素
| d = {'name': 'Tom', 'age': 18} |
| d['gender'] = 'Male' |
| print(d) |
# 5.4.2 修改已有键值对
| d = {'name': 'Tom', 'age': 18} |
| d['age'] = 19 |
| print(d) |
# 5.4.3 删除键值对
| d = {'name': 'Tom', 'age': 18, 'gender': 'Male'} |
| |
| age = d.pop('age') |
| print(age, d) |
| |
| d.clear() |
| print(d) |
| |
| d = {'name': 'Tom', 'age': 18} |
| del d['name'] |
| print(d) |
| del d |
# 注意点
- 字典的
sum() 、 max() 、 min() 操作针对的是键,不是值 - 键必须是不可变类型,否则会引发 TypeError 异常
- 使用方括号访问不存在的键会引发 KeyError 异常,推荐使用 get () 方法
# 5.5 字典的遍历
# 5.5.1 遍历键
| d = {'name': 'Tom', 'age': 18, 'gender': 'Male'} |
| for key in d: |
| print(key) |
| for key in d.keys(): |
| print(key) |
# 5.5.2 遍历值
| d = {'name': 'Tom', 'age': 18, 'gender': 'Male'} |
| for value in d.values(): |
| print(value) |
# 5.5.3 遍历键值对
| d = {'name': 'Tom', 'age': 18, 'gender': 'Male'} |
| for key, value in d.items(): |
| print(key, value) |
# 5.6 字典小结
- 字典是键值对的可变容器
- 键必须是不可变类型,值可以是任何类型
- 提供多种方法访问和修改字典
- 支持遍历键、值、键值对
# 6. 集合
# 6.1 集合的基本特性
- 唯一性:不允许重复元素
- 无序性:不支持索引和切片操作
- 可哈希性:元素必须是不可变类型
# 6.2 集合的创建
# 6.2.1 可变集合创建
| |
| set1 = {1, 2, 3} |
| |
| empty_set = set() |
| |
| set2 = set([1, 2, 3, 3]) |
| set3 = set("Hello") |
# 6.3 集合的常用方法及运算符
# 6.3.1 添加元素
| set1 = {1, 2, 3} |
| set1.add(4) |
# 6.3.2 删除元素
| set1 = {1, 2, 3, 4} |
| set1.remove(3) |
| set1.discard(5) |
| set1.pop() |
| set1.clear() |
# 6.3.3 集合运算
| set1 = {1, 2, 3, 4} |
| set2 = {3, 4, 5, 6} |
| |
| |
| print(set1 & set2) |
| print(set1.intersection(set2)) |
| |
| |
| print(set1 | set2) |
| print(set1.union(set2)) |
| |
| |
| print(set1 - set2) |
| print(set1.difference(set2)) |
| |
| |
| print(set1 ^ set2) |
| print(set1.symmetric_difference(set2)) |
# 6.3.4 其他方法
| set1 = {1, 2, 3} |
| set2 = {2, 3} |
| print(len(set1)) |
| print(set2.issubset(set1)) |
| print(set1.issuperset(set2)) |
| print(set1.copy()) |
# 6.4 不可变集合
| |
| fs = frozenset([1, 2, 3]) |
| |
# 注意点
- 不可变集合没有添加、删除元素的方法
- 不可变集合可以作为字典的键或其他集合的元素
# 6.5 集合小结
- 集合是无序的不重复元素集合
- 分为可变集合和不可变集合
- 提供丰富的集合运算和方法
- 适合用于去重、交集、并集等操作
# 7. 函数
# 7.1 内置函数
| |
| print("Hello World") |
| name = input("请输入姓名:") |
| |
| |
| print(abs(-10)) |
| print(divmod(10, 3)) |
| print(round(3.14159, 2)) |
| print(pow(2, 3)) |
| print(sum([1, 2, 3])) |
| print(min(1, 2, 3)) |
| print(max(1, 2, 3)) |
| |
| |
| print(int(3.14)) |
| print(float(3)) |
| print(str(123)) |
| print(list((1, 2, 3))) |
| print(tuple([1, 2, 3])) |
| print(dict(name='Tom', age=18)) |
| print(set([1, 2, 3, 3])) |
| |
| |
| print(range(5)) |
| print(len([1, 2, 3])) |
| print(sorted([3, 1, 2])) |
| print(list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4]))) |
| print(list(map(lambda x: x * 2, [1, 2, 3]))) |
| |
| |
| print(id(1)) |
| print(type(1)) |
# 7.2 自定义函数
# 定义与调用
| def greet(name): |
| """这是一个问候函数""" |
| return f"Hello, {name}!" |
| |
| |
| print(greet("Tom")) |
# 参数传递
| def func(a, b): |
| a += 1 |
| b.append(4) |
| return a, b |
| |
| x = 1 |
| y = [1, 2, 3] |
| x, y = func(x, y) |
| print(x) |
| print(y) |
# 注意点
- Python 中函数参数传递是 “对象引用传递”
- 不可变对象(数字、字符串、元组)在函数内修改不会影响外部
- 可变对象(列表、字典、集合)在函数内修改会影响外部
# 7.3 函数的特殊参数
# 7.3.1 默认参数
| def func(a, b=10): |
| return a + b |
| |
| print(func(5)) |
| print(func(5, 20)) |
# 注意点
- 默认参数必须放在非默认参数之后
- 默认参数的值在函数定义时计算,不是在调用时计算
- 默认参数应该使用不可变对象,避免使用可变对象(如列表)
# 7.3.2 关键字参数
| def func(a, b): |
| return a + b |
| |
| print(func(a=5, b=10)) |
| print(func(b=10, a=5)) |
| print(func(5, b=10)) |
| |
# 注意点
- 关键字参数必须放在位置参数之后
- 可以通过关键字参数改变参数顺序
- 关键字参数提高了代码的可读性
# 7.3.3 可变长参数
| |
| def func(*args): |
| return args |
| |
| print(func(1, 2, 3)) |
| |
| |
| def func(**kwargs): |
| return kwargs |
| |
| print(func(name='Tom', age=18)) |
| |
| |
| def func(a, *args, **kwargs): |
| return a, args, kwargs |
| |
| print(func(1, 2, 3, name='Tom', age=18)) |
# 7.4 lambda 函数
| |
| add = lambda x, y: x + y |
| print(add(5, 10)) |
| |
| |
| lst = [1, 2, 3, 4, 5] |
| print(list(map(lambda x: x * 2, lst))) |
| print(list(filter(lambda x: x % 2 == 0, lst))) |
# 注意点
- lambda 函数只能包含一个表达式
- lambda 函数没有函数名,是匿名函数
- 适合定义简单的一次性函数
# 7.5 变量作用域
# 局部变量
| def func(): |
| x = 10 |
| print(x) |
| |
| func() |
| |
# 全局变量
| x = 10 |
| |
| def func(): |
| print(x) |
| |
| func() |
| |
| |
| def func(): |
| global x |
| x = 20 |
| |
| func() |
| print(x) |
# 注意点
- 局部变量只在函数内部有效
- 全局变量在整个程序中有效
- 在函数内修改全局变量需要使用
global 关键字 global 关键字不能同时赋值,如 global x = 20 是错误的
# 7.6 递归函数
| def factorial(n): |
| """计算n的阶乘""" |
| if n == 0: |
| return 1 |
| else: |
| return n * factorial(n - 1) |
| |
| print(factorial(5)) |
# 注意点
- 递归函数必须有终止条件
- 递归深度不能过大,否则会引发栈溢出
- 递归函数的执行效率较低,可考虑使用迭代代替
# 7.7 main 函数
| def main(): |
| print("这是主函数") |
| |
| if __name__ == "__main__": |
| main() |
# 说明
__name__ 是 Python 的内置变量- 当直接运行脚本时,
__name__ 的值为 __main__ - 当作为模块导入时,
__name__ 的值为模块名 - 使用
if __name__ == "__main__": 可以确保主函数只在直接运行脚本时执行
# 7.8 函数小结
- 函数是组织代码的基本单位
- Python 提供丰富的内置函数
- 支持自定义函数,参数传递灵活
- 支持 lambda 函数、递归函数等高级特性
# 8. 面向对象程序设计
# 8.1 类与对象
# 类的定义
| class Person: |
| """人这个类""" |
| |
| species = "人类" |
| |
| |
| def __init__(self, name, age): |
| |
| self.name = name |
| self.age = age |
| |
| |
| def greet(self): |
| return f"你好,我是{self.name},今年{self.age}岁。" |
| |
| |
| p = Person("Tom", 18) |
| print(p.greet()) |
# 类成员的可访问范围
- 公有成员:默认,可在类内外访问
- 保护成员:以单下划线开头(如
_name ),建议仅供类和子类内部使用 - 私有成员:以双下划线开头(如
__name ),只能在类内部访问,外部无法直接访问 - 特殊成员:以双下划线开头和结尾(如
__init__ ),具有特殊意义
# 8.2 属性
# 8.2.1 成员属性
| class Person: |
| def __init__(self, name, age): |
| self.name = name |
| self._age = age |
| self.__salary = 5000 |
| |
| |
| def get_salary(self): |
| return self.__salary |
| |
| p = Person("Tom", 18) |
| print(p.name) |
| print(p._age) |
| |
| print(p.get_salary()) |
# 8.2.2 @property 装饰器
| class Person: |
| def __init__(self, name, age): |
| self.name = name |
| self._age = age |
| |
| @property |
| def age(self): |
| return self._age |
| |
| @age.setter |
| def age(self, value): |
| if value > 0 and value < 120: |
| self._age = value |
| else: |
| raise ValueError("年龄必须在0-120之间") |
| |
| @age.deleter |
| def age(self): |
| del self._age |
| |
| p = Person("Tom", 18) |
| print(p.age) |
| p.age = 20 |
| print(p.age) |
| |
| del p.age |
| |
# 8.2.3 类属性
| class Person: |
| count = 0 |
| |
| def __init__(self, name): |
| self.name = name |
| Person.count += 1 |
| |
| print(Person.count) |
| p1 = Person("Tom") |
| print(Person.count) |
| p2 = Person("Jerry") |
| print(Person.count) |
# 8.2.4 特殊属性
| 属性 | 说明 |
|---|
__dict__ | 对象的属性字典 |
__class__ | 对象所属的类 |
__name__ | 类名 |
__qualname__ | 类的限定名称 |
__module__ | 类所在的模块 |
__bases__ | 类的基类元组 |
__mro__ | 方法解析顺序 |
__doc__ | 类的文档字符串 |
# 8.2.5 动态添加 / 删除属性
| class Person: |
| def __init__(self, name): |
| self.name = name |
| |
| p = Person("Tom") |
| p.age = 18 |
| print(p.age) |
| |
| import types |
| p.greet = types.MethodType(lambda self: f"你好,我是{self.name}", p) |
| print(p.greet()) |
| |
| |
| del p.age |
| |
| |
| |
| setattr(p, "gender", "男") |
| print(p.gender) |
| delattr(p, "gender") |
| |
# 8.3 方法
# 8.3.1 实例方法
| class Person: |
| def __init__(self, name): |
| self.name = name |
| |
| def greet(self): |
| return f"你好,我是{self.name}" |
| |
| p = Person("Tom") |
| print(p.greet()) |
# 8.3.2 类方法
| class Person: |
| count = 0 |
| |
| def __init__(self, name): |
| self.name = name |
| Person.count += 1 |
| |
| @classmethod |
| def get_count(cls): |
| return cls.count |
| |
| p1 = Person("Tom") |
| p2 = Person("Jerry") |
| print(Person.get_count()) |
| print(p1.get_count()) |
# 8.3.3 静态方法
| class Person: |
| @staticmethod |
| def say_hello(): |
| return "Hello!" |
| |
| print(Person.say_hello()) |
| p = Person() |
| print(p.say_hello()) |
# 8.3.4 特殊方法
| class Person: |
| def __init__(self, name, age): |
| self.name = name |
| self.age = age |
| |
| def __str__(self): |
| return f"Person(name='{self.name}', age={self.age})" |
| |
| def __repr__(self): |
| return f"Person('{self.name}', {self.age})" |
| |
| def __len__(self): |
| return self.age |
| |
| def __call__(self): |
| return f"{self.name}被调用了" |
| |
| p = Person("Tom", 18) |
| print(p) |
| print(repr(p)) |
| print(len(p)) |
| print(p()) |
# 8.3.5 动态添加 / 删除方法
| import types |
| |
| class Person: |
| def __init__(self, name): |
| self.name = name |
| |
| |
| def greet(self): |
| return f"你好,我是{self.name}" |
| |
| p = Person("Tom") |
| p.greet = types.MethodType(greet, p) |
| print(p.greet()) |
| |
| |
| @classmethod |
| def get_class_name(cls): |
| return cls.__name__ |
| |
| Person.get_class_name = get_class_name |
| print(Person.get_class_name()) |
| |
| |
| @staticmethod |
| def say_hello(): |
| return "Hello!" |
| |
| Person.say_hello = say_hello |
| print(Person.say_hello()) |
| |
| |
| del p.greet |
| del Person.get_class_name |
| del Person.say_hello |
# 8.4 运算符重载
| 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 __sub__(self, other): |
| return Vector(self.x - other.x, self.y - other.y) |
| |
| def __mul__(self, scalar): |
| return Vector(self.x * scalar, self.y * scalar) |
| |
| def __eq__(self, other): |
| return self.x == other.x and self.y == other.y |
| |
| def __str__(self): |
| return f"Vector({self.x}, {self.y})" |
| |
| v1 = Vector(1, 2) |
| v2 = Vector(3, 4) |
| v3 = v1 + v2 |
| print(v3) |
| v4 = v1 - v2 |
| print(v4) |
| v5 = v1 * 2 |
| print(v5) |
| print(v1 == v2) |
# 8.5 继承
# 8.5.1 单继承
| class Animal: |
| def __init__(self, name): |
| self.name = name |
| |
| def eat(self): |
| return f"{self.name}在吃东西" |
| |
| class Dog(Animal): |
| def __init__(self, name, breed): |
| super().__init__(name) |
| self.breed = breed |
| |
| def bark(self): |
| return f"{self.name}在汪汪叫" |
| |
| |
| dog = Dog("Tom", "金毛") |
| print(dog.eat()) |
| print(dog.bark()) |
# 8.5.2 多继承
| class A: |
| def method(self): |
| return "A.method" |
| |
| class B: |
| def method(self): |
| return "B.method" |
| |
| class C(A, B): |
| pass |
| |
| class D(B, A): |
| pass |
| |
| c = C() |
| print(c.method()) |
| |
| d = D() |
| print(d.method()) |
# 注意点
- Python 支持单继承和多继承
- 多继承时,方法解析顺序(MRO)决定了调用哪个父类的方法
- 推荐使用
super() 调用父类方法,不推荐直接使用父类名
# 8.6 多态性
| class Animal: |
| def speak(self): |
| pass |
| |
| class Dog(Animal): |
| def speak(self): |
| return "汪汪汪" |
| |
| class Cat(Animal): |
| def speak(self): |
| return "喵喵喵" |
| |
| class Bird(Animal): |
| def speak(self): |
| return "叽叽喳喳" |
| |
| def make_animal_speak(animal): |
| return animal.speak() |
| |
| |
| dog = Dog() |
| cat = Cat() |
| bird = Bird() |
| |
| print(make_animal_speak(dog)) |
| print(make_animal_speak(cat)) |
| print(make_animal_speak(bird)) |
# 8.7 面向对象程序设计小结
- 面向对象程序设计的核心是类和对象
- 类封装了数据和方法
- 支持继承、多态等特性
- 提供丰富的特殊方法和装饰器
# 9. 文件和目录操作
# 9.1 文件类型与基本操作
# 9.1.1 文件类型
- 文本文件:由字符组成,如.txt、.py 文件
- 二进制文件:由字节组成,如图片、音频、视频文件
# 9.1.2 文件基本操作
- 打开文件:使用
open() 函数 - 读写文件:使用文件对象的方法
- 关闭文件:使用
close() 方法或 with 语句
| |
| f = open('file.txt', 'r') |
| content = f.read() |
| f.close() |
| |
| |
| with open('file.txt', 'r') as f: |
| content = f.read() |
# 9.2 文件打开模式
# 9.2.1 基本模式
| 模式 | 含义 | 文件不存在时 |
|---|
| r | 只读 | 报错 |
| w | 只写 | 创建新文件 |
| a | 追加 | 创建新文件 |
| + | 读写 | 与其他模式组合使用 |
| b | 二进制模式 | 与其他模式组合使用 |
| t | 文本模式(默认) | 与其他模式组合使用 |
# 9.2.2 常用组合模式
- r+:读写模式,文件指针位于起始位置
- w+:读写模式,先清空文件内容
- a+:读写模式,文件指针位于末尾
- rb:二进制只读模式
- wb:二进制只写模式
- ab:二进制追加模式
- rb+:二进制读写模式
- wb+:二进制读写模式,先清空内容
- ab+:二进制追加模式,指针位于末尾
# 注意点
+ 不能单独使用,必须与其他模式组合r 、 r+ 、 rb 、 rb+ 要求文件必须存在w 、 w+ 、 wb 、 wb+ 、 a 、 a+ 、 ab 、 ab+ 在文件不存在时会创建新文件
# 9.3 文件读写方法
# 9.3.1 读取方法
| with open('file.txt', 'r') as f: |
| content = f.read() |
| line = f.readline() |
| lines = f.readlines() |
# 9.3.2 写入方法
| with open('file.txt', 'w') as f: |
| f.write('Hello World') |
| f.writelines(['Line 1\n', 'Line 2\n']) |
# 9.3.3 其他方法
| with open('file.txt', 'r') as f: |
| pos = f.tell() |
| f.seek(0) |
| f.seek(0, 2) |
| f.flush() |
# 注意点
- 只有以二进制模式 (
b ) 打开的文件,才允许文件指针向后移动 seek() 方法的 whence 参数取 1 和 2 的用法只能在二进制文件中使用write() 只能将字符串写入文件
# 9.3.4 struct 模块(二进制数据处理)
| import struct |
| |
| |
| packed_data = struct.pack('i f s', 1, 3.14, b'hello') |
| print(packed_data) |
| |
| |
| unpacked_data = struct.unpack('i f s', packed_data) |
| print(unpacked_data) |
| |
| |
| size = struct.calcsize('i f s') |
| print(size) |
# 9.3.5 pickle 模块(对象序列化)
| import pickle |
| |
| |
| data = {'name': 'Tom', 'age': 18, 'scores': [90, 85, 95]} |
| with open('data.pkl', 'wb') as f: |
| pickle.dump(data, f) |
| |
| |
| with open('data.pkl', 'rb') as f: |
| loaded_data = pickle.load(f) |
| print(loaded_data) |
# 9.4 CSV 文件操作
| import csv |
| |
| |
| with open('data.csv', 'w', newline='') as f: |
| writer = csv.writer(f) |
| writer.writerow(['name', 'age', 'city']) |
| writer.writerows([ |
| ['Tom', 18, 'Beijing'], |
| ['Jerry', 20, 'Shanghai'] |
| ]) |
| |
| |
| with open('data.csv', 'r') as f: |
| reader = csv.reader(f) |
| for row in reader: |
| print(row) |
| |
| |
| with open('data.csv', 'w', newline='') as f: |
| fieldnames = ['name', 'age', 'city'] |
| writer = csv.DictWriter(f, fieldnames=fieldnames) |
| writer.writeheader() |
| writer.writerow({'name': 'Tom', 'age': 18, 'city': 'Beijing'}) |
| writer.writerow({'name': 'Jerry', 'age': 20, 'city': 'Shanghai'}) |
| |
| with open('data.csv', 'r') as f: |
| reader = csv.DictReader(f) |
| for row in reader: |
| print(row['name'], row['age'], row['city']) |
# 注意点
- 参数
newline='' 不能省略,否则会出现空行 csv.reader 返回的每个元素是一个列表
# 9.5 Excel 文件操作
| import openpyxl |
| |
| |
| wb = openpyxl.Workbook() |
| ws = wb.active |
| ws.title = 'Sheet1' |
| |
| |
| ws['A1'] = 'Name' |
| ws['B1'] = 'Age' |
| ws['C1'] = 'City' |
| ws.append(['Tom', 18, 'Beijing']) |
| ws.append(['Jerry', 20, 'Shanghai']) |
| |
| |
| wb.save('data.xlsx') |
| |
| |
| wb = openpyxl.load_workbook('data.xlsx') |
| print(wb.sheetnames) |
| ws = wb['Sheet1'] |
| |
| |
| print(ws['A1'].value) |
| print(ws.cell(row=1, column=1).value) |
| |
| |
| for row in ws.iter_rows(min_row=1, max_row=3, min_col=1, max_col=3): |
| for cell in row: |
| print(cell.value, end=' ') |
| print() |
# 9.6 图像文件操作
| from PIL import Image |
| |
| |
| img = Image.open('image.jpg') |
| |
| |
| print(img.size) |
| print(img.mode) |
| print(img.format) |
| |
| |
| img_resized = img.resize((200, 200)) |
| img_rotated = img.rotate(45) |
| img_cropped = img.crop((100, 100, 300, 300)) |
| |
| |
| img_resized.save('image_resized.jpg') |
| img_rotated.save('image_rotated.jpg') |
| img_cropped.save('image_cropped.jpg') |
# 9.7 JSON 文件操作
| import json |
| |
| |
| person = {'name': 'Tom', 'age': 18, 'city': 'Beijing'} |
| json_str = json.dumps(person, ensure_ascii=False) |
| |
| |
| with open('person.json', 'w', encoding='utf-8') as f: |
| json.dump(person, f, ensure_ascii=False, indent=4) |
| |
| |
| with open('person.json', 'r', encoding='utf-8') as f: |
| person_dict = json.load(f) |
| print(person_dict['name'], person_dict['age']) |
# 9.8 os 和 os.path 模块
| import os |
| |
| |
| cwd = os.getcwd() |
| print(cwd) |
| |
| |
| os.chdir('d:\\') |
| |
| |
| os.mkdir('test_dir') |
| os.makedirs('test_dir1\\test_dir2') |
| |
| |
| os.rmdir('test_dir') |
| os.removedirs('test_dir1\\test_dir2') |
| |
| |
| files = os.listdir('.') |
| |
| |
| for root, dirs, files in os.walk('.'): |
| for file in files: |
| print(os.path.join(root, file)) |
| |
| |
| file_path = os.path.join('dir', 'file.txt') |
| print(os.path.exists(file_path)) |
| print(os.path.isfile(file_path)) |
| print(os.path.isdir(file_path)) |
| print(os.path.abspath(file_path)) |
| print(os.path.split(file_path)) |
| print(os.path.splitext(file_path)) |
| |
| |
| print(os.path.getsize(file_path)) |
| print(os.path.getatime(file_path)) |
| print(os.path.getmtime(file_path)) |
# 9.9 shutil 模块
| import shutil |
| |
| |
| shutil.copyfile('src.txt', 'dst.txt') |
| shutil.copy('src.txt', 'dst.txt') |
| |
| |
| shutil.copytree('src_dir', 'dst_dir') |
| |
| |
| shutil.move('src.txt', 'dst_dir/') |
| |
| |
| shutil.rmtree('dir_to_delete') |
| |
| |
| shutil.make_archive('archive', 'zip', 'dir_to_archive') |
| |
| |
| shutil.unpack_archive('archive.zip', 'dst_dir') |
# 10. 异常处理
异常处理是 Python 中处理程序运行时错误的机制,通过捕获和处理异常,可以提高程序的健壮性和用户体验,防止程序因错误而意外终止。
# 10.1 异常类
Python 中的异常类层次结构如下:
BaseException :所有异常的基类Exception :所有非系统退出异常的基类SyntaxError :语法错误TypeError :类型错误ValueError :值错误NameError :名称错误IndexError :索引错误KeyError :键错误IOError / OSError :输入输出错误ZeroDivisionError :除零错误
# 10.2 异常处理结构
异常处理结构是 Python 中捕获和处理异常的核心语法,通过 try-except-else-finally 结构可以灵活控制异常的处理流程和资源的释放。
| try: |
| |
| result = 10 / 0 |
| except ZeroDivisionError as e: |
| |
| print(f'除零错误:{e}') |
| except (TypeError, ValueError) as e: |
| |
| print(f'类型或值错误:{e}') |
| except Exception as e: |
| |
| print(f'发生错误:{e}') |
| else: |
| |
| print('执行成功') |
| finally: |
| |
| print('清理工作') |
# 10.3 抛出异常
抛出异常是 Python 中主动触发异常的机制,通过 raise 语句可以在程序中自定义异常的触发条件,将错误信息传递给上层调用者。
| |
| raise ValueError('值错误') |
| |
| |
| raise ZeroDivisionError('除数不能为零') |
# 10.4 自定义异常
自定义异常是 Python 中扩展异常体系的机制,通过创建自定义异常类,可以为特定业务场景定义专门的异常类型,提高代码的可读性和可维护性。
| |
| class MyException(Exception): |
| def __init__(self, message): |
| self.message = message |
| super().__init__(self.message) |
| |
| |
| try: |
| raise MyException('自定义异常') |
| except MyException as e: |
| print(f'捕获自定义异常:{e}') |
# 10.5 断言
断言是 Python 中用于调试的机制,通过 assert 语句可以在程序中插入检查点,验证某个条件是否为真,如果条件为假则触发 AssertionError 异常。
| |
| x = 5 |
| assert x > 0, 'x必须大于0' |
| |
| |
| try: |
| assert x < 0, 'x必须小于0' |
| except AssertionError as e: |
| print(f'断言失败:{e}') |
# 注意点
- 断言主要用于调试阶段,不应该用于生产环境的错误处理
- 可以通过
-O 参数运行 Python 来禁用断言
# 11. 常用库
# 11.1 库的导入方式
库的导入方式是 Python 中使用外部库或模块的基础机制,通过不同的导入方式可以灵活控制模块中函数和变量的访问范围和命名空间。
# 11.1.1 导入整个库
| import math |
| import random as rd |
# 11.1.2 导入特定函数
| from math import ceil, sqrt |
| from math import * |
| from random import randint as ri |
# 11.1.3 第三方库安装
| pip install numpy pandas matplotlib |
| pip list |
# 11.2 math 库
math 库是 Python 的标准数学库,提供了丰富的数学函数和常量,用于进行各种数学计算。该库包含了基本运算、三角函数、指数对数、组合数学等多种功能,适用于科学计算、数据分析等场景。
| import math |
| |
| print(math.ceil(3.14)) |
| print(math.floor(3.14)) |
| print(math.sqrt(16)) |
| print(math.factorial(5)) |
| print(math.gcd(12, 18)) |
| print(math.exp(1)) |
| print(math.log(10)) |
| print(math.pow(2, 3)) |
| print(math.sin(math.pi/2)) |
# 11.3 random 库
random 库是 Python 的标准随机数生成库,提供了各种随机数生成和随机选择功能。该库可用于模拟、游戏开发、数据分析中的随机抽样等场景,能够生成不同分布的随机数。
| import random |
| |
| |
| random.seed(123) |
| |
| print(random.randint(1, 10)) |
| print(random.randrange(0, 10, 2)) |
| print(random.uniform(1, 10)) |
| print(random.choice(['a', 'b', 'c'])) |
| |
| lst = [1, 2, 3, 4, 5] |
| random.shuffle(lst) |
| print(lst) |
| |
| print(random.sample([1, 2, 3, 4, 5], 3)) |
# 11.4 datetime 库
datetime 库是 Python 的标准日期时间处理库,提供了用于处理日期、时间、时间间隔和时间戳的类和函数。该库能够满足各种日期时间的计算、格式化和转换需求,是处理时间相关数据的核心工具。
| import datetime |
| |
| |
| now = datetime.datetime.now() |
| utc_now = datetime.datetime.utcnow() |
| |
| |
| dt = datetime.datetime(2023, 12, 25, 10, 30, 45) |
| |
| |
| print(dt.date()) |
| print(dt.time()) |
| |
| |
| print(dt.strftime('%Y-%m-%d %H:%M:%S')) |
| |
| |
| delta = datetime.timedelta(days=7, hours=2) |
| new_dt = dt + delta |
# 11.5 NumPy 库
NumPy 库(Numerical Python)是 Python 科学计算的核心库,提供了高性能的多维数组对象(ndarray)和丰富的数组操作函数。该库支持矢量化运算和广播机制,能够高效处理大规模数据,是数据分析、机器学习、图像处理等领域的基础依赖库。
| import numpy as np |
| |
| |
| arr1 = np.array([1, 2, 3, 4, 5]) |
| arr2 = np.arange(0, 10, 2) |
| arr3 = np.linspace(0, 1, 5) |
| arr4 = np.zeros((2, 3)) |
| arr5 = np.ones((2, 3)) |
| arr6 = np.eye(3) |
| |
| |
| print(arr1.shape) |
| print(arr1.ndim) |
| print(arr1.size) |
| print(arr1.dtype) |
| |
| |
| print(arr1 + 2) |
| print(arr1 * 2) |
| print(arr1 + arr2) |
| print(arr1 * arr2) |
| |
| |
| print(arr1[0]) |
| print(arr1[1:4]) |
| print(arr1[arr1 > 2]) |
| |
| |
| print(np.reshape(arr1, (5, 1))) |
| print(np.transpose(arr4)) |
| print(np.concatenate((arr4, arr5), axis=0)) |
# 11.6 pandas 库
pandas 库是 Python 用于数据处理和分析的强大库,提供了高效的数据结构(如 Series 和 DataFrame)和丰富的数据操作功能。该库支持数据导入导出、数据清洗、数据转换、数据聚合和统计分析等操作,是数据分析和数据科学领域的必备工具。
| import pandas as pd |
| |
| |
| s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e']) |
| |
| |
| df = pd.DataFrame({ |
| 'name': ['Tom', 'Jerry', 'Alice'], |
| 'age': [18, 20, 22], |
| 'city': ['Beijing', 'Shanghai', 'Guangzhou'] |
| }) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| print(df['name']) |
| print(df.loc[0]) |
| print(df.iloc[0]) |
| print(df.at[0, 'name']) |
| print(df.iat[0, 0]) |
| |
| |
| print(df.isna()) |
| print(df.fillna(0)) |
| print(df.dropna()) |
| print(df.drop_duplicates()) |
| print(df.replace(18, 19)) |
| |
| |
| print(df.info()) |
| print(df.describe()) |
| print(df.head()) |
| print(df.tail()) |
| print(df['age'].value_counts()) |
| |
| |
| grouped = df.groupby('city') |
| print(grouped['age'].mean()) |
# 11.7 matplotlib 库
matplotlib 库是 Python 的绘图库,提供了丰富的绘图功能,可以创建各种类型的图表,如折线图、柱状图、散点图、直方图等。该库支持自定义图表样式、添加注释和图例,是数据可视化和科学绘图的重要工具。
| import matplotlib.pyplot as plt |
| |
| |
| plt.rcParams['font.sans-serif'] = ['SimHei'] |
| plt.rcParams['axes.unicode_minus'] = False |
| |
| |
| x = [1, 2, 3, 4, 5] |
| y = [2, 4, 6, 8, 10] |
| |
| |
| plt.figure(figsize=(8, 6)) |
| |
| |
| plt.plot(x, y, color='red', linestyle='--', linewidth=2, marker='o', label='折线图') |
| |
| |
| |
| |
| |
| plt.xlabel('X轴', fontsize=12) |
| plt.ylabel('Y轴', fontsize=12) |
| plt.title('示例图表', fontsize=14) |
| |
| |
| plt.xlim(0, 6) |
| plt.ylim(0, 12) |
| |
| |
| plt.grid(True, linestyle='--', alpha=0.7) |
| |
| |
| plt.legend() |
| |
| |
| plt.show() |
# 总结
本笔记系统地整理了 Python 的核心知识点,包括:
- 字符串、列表、元组、字典、集合等数据类型
- 数据类型转换和常用函数
- 函数的定义、调用和参数传递
- 面向对象程序设计的核心概念
- 文件和目录操作(包括文本 / 二进制文件、CSV、Excel、JSON、图像文件等)
- 异常处理机制(包括异常类、try-except 结构、自定义异常等)
- 常用库(包括标准库和第三方库如 NumPy、pandas、matplotlib 等)