Python 基础知识
写在前面:本文适合 Python 初学者及希望系统复习 Python 基础的开发者。全文涵盖从 Python 概述到常用标准库的核心知识点,每个知识点均配有可运行的代码实例,帮助你快速上手并深入理解。
目录
- [一、Python 概述](#一、Python 概述)
- [二、Python 开发环境搭建](#二、Python 开发环境搭建)
- 三、基础语法
- 四、流程控制
- 五、数据结构
- 六、函数
- 七、面向对象编程(OOP)
- 八、异常处理
- 九、文件操作
- 十、模块与包
- 十一、常用标准库
- 总结
一、Python 概述
1.1 Python 的发展历史
Python 是由荷兰人 Guido van Rossum (吉多·范罗苏姆)于 1989 年圣诞节 期间开始设计,并于 1991 年 首次发布的一种高级编程语言。Python 的名字来源于 Guido 喜欢的英国喜剧团体 Monty Python(蒙提·派森),而非蟒蛇。
Python 的发展历程中的几个重要版本:
| 版本 | 发布年份 | 重要特性 |
|---|---|---|
| Python 0.9.0 | 1991 | 第一个公开发布版本 |
| Python 2.0 | 2000 | 列表推导式、垃圾回收机制 |
| Python 2.4 | 2004 | decorator 装饰器 |
| Python 3.0 | 2008 | 不兼容 Python 2 的重大更新(print 变为函数、Unicode 默认编码) |
| Python 3.6 | 2016 | f-string、类型注解、异步生成器 |
| Python 3.8 | 2019 | 海象运算符 :=、仅位置参数 / |
| Python 3.10 | 2021 | 结构化模式匹配(match-case)、类型联合 `X |
| Python 3.12 | 2023 | 更好的错误信息、性能优化、类型参数语法 |
注意:Python 2 已于 2020 年 1 月 1 日停止维护,建议所有新项目使用 Python 3。
1.2 Python 的核心特点
- 简洁易读:语法简洁,代码可读性极高,适合初学者入门。
- 解释型语言:无需编译,逐行解释执行。
- 动态类型:变量无需声明类型,运行时自动推断。
- 跨平台:支持 Windows、Linux、macOS 等主流操作系统。
- 面向对象:全面支持面向对象编程。
- 丰富的标准库:内置大量模块,开箱即用。
- 强大的第三方生态:PyPI 上有数十万个第三方包。
- 胶水语言:可以方便地调用 C/C++ 等其他语言编写的模块。
1.3 Python 的应用领域
| 领域 | 说明 | 常用库 |
|---|---|---|
| Web 开发 | 后端服务、API | Django、Flask、FastAPI |
| 数据分析 | 数据处理、清洗 | Pandas、NumPy |
| 人工智能 | 机器学习、深度学习 | PyTorch、TensorFlow、scikit-learn |
| 爬虫 | 网页数据采集 | Scrapy、Requests、BeautifulSoup |
| 自动化运维 | 脚本、工具开发 | Ansible、Fabric |
| 科学计算 | 数值计算、可视化 | SciPy、Matplotlib |
| 桌面应用 | GUI 程序 | PyQt、Tkinter |
1.4 Python 之禅
在 Python 交互式环境中输入 import this,会显示 Tim Peters 编写的 "The Zen of Python"(Python 之禅),这体现了 Python 的设计哲学:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
...
核心精神:优美胜于丑陋,明确胜于隐晦,简单胜于复杂,可读性很重要。
二、Python 开发环境搭建
2.1 Python 下载与安装
- 访问 Python 官网下载:https://www.python.org/downloads/
- 选择适合自己操作系统的版本下载并安装。
- Windows 安装时务必勾选 "Add Python to PATH"。
2.2 验证安装
bash
python --version # 查看 Python 版本
pip --version # 查看 pip 版本
2.3 第一个 Python 程序
python
# hello.py
print("Hello, World!")
运行:
bash
python hello.py
输出:
Hello, World!
2.4 常用开发工具
| 工具 | 特点 |
|---|---|
| VS Code | 轻量级、插件丰富、免费 |
| PyCharm | 专业 Python IDE、功能强大 |
| Jupyter Notebook | 适合数据分析、交互式编程 |
| Sublime Text | 轻量级文本编辑器 |
2.5 pip 包管理
bash
# 安装包
pip install requests
# 安装指定版本
pip install requests==2.28.0
# 升级包
pip install --upgrade requests
# 卸载包
pip uninstall requests
# 查看已安装的包
pip list
# 导出依赖
pip freeze > requirements.txt
# 安装依赖
pip install -r requirements.txt
2.6 虚拟环境
bash
# 创建虚拟环境
python -m venv myenv
# 激活虚拟环境(Windows)
myenv\Scripts\activate
# 激活虚拟环境(Linux/macOS)
source myenv/bin/activate
# 退出虚拟环境
deactivate
三、基础语法
3.1 注释
python
# 这是单行注释
"""
这是多行注释(使用三引号字符串)
可以跨越多行
通常用于函数/类的文档字符串(docstring)
"""
'''
也可以用单引号的三引号
作为多行注释
'''
3.2 缩进
Python 使用缩进 来表示代码块,而不是大括号 {}。这是 Python 最显著的语法特点。
python
# 正确:缩进一致(推荐4个空格)
if True:
print("缩进4个空格")
print("同一代码块")
# 错误:缩进不一致
# if True:
# print("4个空格")
# print("5个空格") # IndentationError!
PEP 8 规范 :推荐使用 4 个空格进行缩进,不要混用空格和 Tab。
3.3 变量与命名规范
Python 是动态类型语言,变量无需声明类型,赋值即创建。
python
# 变量赋值
name = "张三" # 字符串
age = 25 # 整数
height = 1.75 # 浮点数
is_student = True # 布尔值
# 多重赋值
a, b, c = 1, 2, 3
print(a, b, c) # 1 2 3
# 链式赋值
x = y = z = 100
print(x, y, z) # 100 100 100
# 交换变量(无需临时变量)
a, b = b, a
print(a, b) # 2 1
# 查看变量类型
print(type(name)) # <class 'str'>
print(type(age)) # <class 'int'>
print(type(height)) # <class 'float'>
print(type(is_student)) # <class 'bool'>
命名规范(PEP 8):
| 类型 | 规范 | 示例 |
|---|---|---|
| 变量名/函数名 | 小写+下划线(snake_case) | user_name、get_student_info |
| 类名 | 大驼峰(PascalCase) | HelloWorld、StudentManager |
| 常量名 | 全大写+下划线 | MAX_VALUE、DEFAULT_PORT |
| 模块名 | 小写+下划线 | my_module、utils |
| 私有成员 | 前缀下划线 | _private_var、__name_mangling |
3.4 基本数据类型
python
# ===== 1. 整数(int) =====
a = 100
b = -50
c = 0xFF # 十六进制
d = 0o77 # 八进制
e = 0b1010 # 二进制
print(f"整数: {a}, {b}, {c}, {d}, {e}") # 100, -50, 255, 63, 10
# Python 的整数没有大小限制(不会溢出)
big = 10 ** 100
print(f"10的100次方: {big}")
# ===== 2. 浮点数(float) =====
f1 = 3.14
f2 = 2.5e10 # 科学计数法 = 2.5 * 10^10
f3 = 1.0
print(f"浮点数: {f1}, {f2}, {f3}")
# 浮点数精度问题
print(0.1 + 0.2) # 0.30000000000000004
# 使用 decimal 模块解决精度问题
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2')) # 0.3
# ===== 3. 字符串(str) =====
s1 = '单引号字符串'
s2 = "双引号字符串"
s3 = """三引号
可以跨行
的字符串"""
s4 = f"格式化字符串: name={name}, age={age}" # f-string (Python 3.6+)
print(s1)
print(s2)
print(s3)
print(s4)
# 字符串常用操作
text = "Hello, Python"
print(f"长度: {len(text)}") # 13
print(f"大写: {text.upper()}") # HELLO, PYTHON
print(f"小写: {text.lower()}") # hello, python
print(f"首字母大写: {text.title()}") # Hello, Python
print(f"替换: {text.replace('Python', 'World')}") # Hello, World
print(f"分割: {text.split(', ')}") # ['Hello', 'Python']
print(f"查找: {text.find('Python')}") # 7(返回索引,找不到返回-1)
print(f"切片: {text[0:5]}") # Hello
print(f"反转: {text[::-1]}") # nohtyP ,olleH
# 字符串格式化
name = "张三"
age = 25
# 方式1:f-string(推荐)
print(f"我叫{name},今年{age}岁")
# 方式2:format方法
print("我叫{},今年{}岁".format(name, age))
# 方式3:百分号(旧式)
print("我叫%s,今年%d岁" % (name, age))
# ===== 4. 布尔值(bool) =====
t = True
f = False
print(f"True and False: {t and f}") # False
print(f"True or False: {t or f}") # True
print(f"not True: {not t}") # False
# 布尔值为 False 的值
print(bool(0)) # False
print(bool("")) # False(空字符串)
print(bool([])) # False(空列表)
print(bool(None)) # False
print(bool(0.0)) # False
print(bool("a")) # True
# ===== 5. None 类型 =====
result = None
print(result) # None
print(type(result)) # <class 'NoneType'>
3.5 类型转换
python
# 转换为整数
print(int("123")) # 123
print(int(3.99)) # 3(截断小数部分)
print(int("0xFF", 16)) # 255(十六进制字符串转整数)
print(int("1010", 2)) # 10(二进制字符串转整数)
# 转换为浮点数
print(float("3.14")) # 3.14
print(float(5)) # 5.0
# 转换为字符串
print(str(123)) # "123"
print(str(3.14)) # "3.14"
print(str([1, 2, 3])) # "[1, 2, 3]"
# 转换为布尔值
print(bool(1)) # True
print(bool(0)) # False
# 转换为列表/元组
print(list("hello")) # ['h', 'e', 'l', 'l', 'o']
print(tuple([1, 2, 3])) # (1, 2, 3)
print(list((1, 2, 3))) # [1, 2, 3]
3.6 运算符
python
# ===== 1. 算术运算符 =====
a, b = 10, 3
print("=== 算术运算符 ===")
print(f"{a} + {b} = {a + b}") # 13
print(f"{a} - {b} = {a - b}") # 7
print(f"{a} * {b} = {a * b}") # 30
print(f"{a} / {b} = {a / b}") # 3.3333...(真除法)
print(f"{a} // {b} = {a // b}") # 3(整除/地板除)
print(f"{a} % {b} = {a % b}") # 1(取余)
print(f"{a} ** {b} = {a ** b}") # 1000(幂运算)
# ===== 2. 比较运算符 =====
print("\n=== 比较运算符 ===")
print(f"{a} > {b}: {a > b}") # True
print(f"{a} < {b}: {a < b}") # False
print(f"{a} >= {b}: {a >= b}") # True
print(f"{a} <= {b}: {a <= b}") # False
print(f"{a} == {b}: {a == b}") # False
print(f"{a} != {b}: {a != b}") # True
# 链式比较(Python 特有)
score = 85
print(f"60 <= 85 <= 100: {60 <= score <= 100}") # True
# ===== 3. 逻辑运算符 =====
print("\n=== 逻辑运算符 ===")
t, f = True, False
print(f"True and False: {t and f}") # False
print(f"True or False: {t or f}") # True
print(f"not True: {not t}") # False
# 短路求值
# and:如果第一个为False,直接返回第一个值
print(0 and 100) # 0
print(1 and 100) # 100
# or:如果第一个为True,直接返回第一个值
print(1 or 100) # 1
print(0 or 100) # 100
# ===== 4. 赋值运算符 =====
print("\n=== 赋值运算符 ===")
num = 10
num += 5 # 等价于 num = num + 5
print(f"num += 5 -> {num}") # 15
num -= 3
print(f"num -= 3 -> {num}") # 12
num *= 2
print(f"num *= 2 -> {num}") # 24
num //= 5
print(f"num //= 5 -> {num}") # 4
num **= 2
print(f"num **= 2 -> {num}") # 16
# 海象运算符 := (Python 3.8+)
print("\n=== 海象运算符 ===")
# 传统写法
text = "Hello World"
length = len(text)
if length > 5:
print(f"字符串长度为 {length}")
# 海象运算符(赋值表达式)
if (n := len(text)) > 5:
print(f"字符串长度为 {n}")
# ===== 5. 成员运算符 =====
print("\n=== 成员运算符 ===")
print("'Py' in 'Python':", 'Py' in 'Python') # True
print("3 in [1, 2, 3]:", 3 in [1, 2, 3]) # True
print("'a' not in 'hello':", 'a' not in 'hello') # True
print("5 in (1, 2, 3):", 5 in (1, 2, 3)) # False
# ===== 6. 身份运算符 =====
print("\n=== 身份运算符 ===")
x = [1, 2, 3]
y = [1, 2, 3]
z = x
print(f"x is z: {x is z}") # True(同一对象)
print(f"x is y: {x is y}") # False(不同对象,值相同)
print(f"x == y: {x == y}") # True(值相等)
print(f"x is not y: {x is not y}") # True
# is 和 == 的区别:
# is 比较内存地址(身份),== 比较值
3.7 输入与输出
python
# ===== 输出 print =====
print("Hello")
print("Hello", "World") # Hello World(默认空格分隔)
print("Hello", "World", sep="-") # Hello-World(自定义分隔符)
print("Hello", end="") # 不换行
print("World")
print("A", "B", "C", sep=" | ", end="!\n") # A | B | C!
# 格式化输出
name = "张三"
age = 25
score = 95.5
print(f"姓名:{name}, 年龄:{age}, 成绩:{score:.1f}")
# 姓名:张三, 年龄:25, 成绩:95.5
# 对齐
for i in range(1, 4):
print(f"第{i:>3}行: {'*' * i}") # 右对齐,宽度3
# 第 1行: *
# 第 2行: **
# 第 3行: ***
# ===== 输入 input =====
# name = input("请输入你的名字: ")
# age = input("请输入你的年龄: ")
# print(f"你好,{name},你今年{age}岁")
# input 返回的是字符串,需要转换类型
# num = int(input("请输入一个整数: "))
# print(f"你输入的整数是: {num}")
四、流程控制
4.1 顺序结构
程序从上到下依次执行,这是最基本的流程。
4.2 条件语句
if-elif-else
python
# ===== 基本 if 语句 =====
age = 18
if age >= 18:
print("你已成年")
# ===== if-else 语句 =====
score = 55
if score >= 60:
print("及格")
else:
print("不及格")
# ===== if-elif-else 语句 =====
score = 85
if score >= 90:
grade = "A (优秀)"
elif score >= 80:
grade = "B (良好)"
elif score >= 70:
grade = "C (中等)"
elif score >= 60:
grade = "D (及格)"
else:
grade = "E (不及格)"
print(f"成绩: {score} -> {grade}") # 成绩: 85 -> B (良好)
# ===== 嵌套条件 =====
age = 25
has_ticket = True
if age >= 18:
if has_ticket:
print("欢迎入场")
else:
print("请先购票")
else:
print("未成年不可入场")
# ===== 条件表达式(三元运算符) =====
num = 10
result = "偶数" if num % 2 == 0 else "奇数"
print(f"{num} 是{result}") # 10 是偶数
# 求最大值
a, b = 10, 20
max_val = a if a > b else b
print(f"最大值: {max_val}") # 20
# ===== 多条件组合 =====
month = 7
if month in (3, 4, 5):
season = "春季"
elif month in (6, 7, 8):
season = "夏季"
elif month in (9, 10, 11):
season = "秋季"
else:
season = "冬季"
print(f"{month}月属于{season}") # 7月属于夏季
# ===== Python 3.10+ 结构化模式匹配(match-case) =====
command = "start"
match command:
case "start":
print("启动服务")
case "stop":
print("停止服务")
case "restart":
print("重启服务")
case _:
print(f"未知命令: {command}")
# 输出: 启动服务
# match-case 匹配数据结构
point = (3, 4)
match point:
case (0, 0):
print("原点")
case (0, y):
print(f"Y轴上,y={y}")
case (x, 0):
print(f"X轴上,x={x}")
case (x, y):
print(f"坐标点: ({x}, {y})")
# 输出: 坐标点: (3, 4)
4.3 循环语句
for 循环
python
# ===== 基本for循环 =====
# 遍历 range
print("range(5):", end=" ")
for i in range(5):
print(i, end=" ") # 0 1 2 3 4
print()
print("range(1,6):", end=" ")
for i in range(1, 6):
print(i, end=" ") # 1 2 3 4 5
print()
print("range(1,10,2):", end=" ")
for i in range(1, 10, 2):
print(i, end=" ") # 1 3 5 7 9(步长为2)
print()
# 遍历字符串
for char in "Python":
print(char, end=" ") # P y t h o n
print()
# 遍历列表
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
print(fruit, end=" ") # 苹果 香蕉 橙子
print()
# 使用 enumerate 获取索引
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 0: 苹果
# 1: 香蕉
# 2: 橙子
# 同时遍历多个序列
names = ["张三", "李四", "王五"]
ages = [20, 22, 21]
for name, age in zip(names, ages):
print(f"{name}: {age}岁")
# 张三: 20岁
# 李四: 22岁
# 王五: 21岁
# ===== 计算1~100的和 =====
total = sum(range(1, 101))
print(f"1~100的和: {total}") # 5050
# 传统方式
total = 0
for i in range(1, 101):
total += i
print(f"1~100的和: {total}") # 5050
# ===== 打印九九乘法表 =====
print("\n九九乘法表:")
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}×{i}={i*j:<4}", end="")
print()
九九乘法表输出:
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
...(以此类推)
1×9=9 2×9=18 3×9=27 ... 9×9=81
while 循环
python
# ===== 基本while循环 =====
# 计算1~100的和
i, total = 1, 0
while i <= 100:
total += i
i += 1
print(f"1~100的和: {total}") # 5050
# ===== 猜数字游戏 =====
import random
target = random.randint(1, 100)
print("猜数字游戏(1~100)")
# 模拟猜数字过程
guess = 50
attempts = 0
while guess != target:
attempts += 1
if guess < target:
print(f"猜了{guess},太小了")
guess += 10
else:
print(f"猜了{guess},太大了")
guess -= 5
print(f"恭喜!猜对了,数字是{target},共猜了{attempts + 1}次")
# ===== while-else(Python特有) =====
# else 块在循环正常结束时执行(非 break 退出)
n = 7
i = 2
while i < n:
if n % i == 0:
print(f"{n} 不是素数(能被{i}整除)")
break
i += 1
else:
print(f"{n} 是素数")
# 7 是素数
4.4 break、continue 和 pass
python
# ===== break:跳出循环 =====
print("=== break ===")
for i in range(1, 11):
if i == 5:
break # i=5时跳出循环
print(i, end=" ") # 1 2 3 4
print()
# ===== continue:跳过本次 =====
print("=== continue ===")
for i in range(1, 11):
if i % 2 == 0:
continue # 跳过偶数
print(i, end=" ") # 1 3 5 7 9
print()
# ===== pass:空语句,占位符 =====
print("=== pass ===")
for i in range(3):
if i == 1:
pass # 什么也不做,保持语法完整
print(i, end=" ") # 0 1 2
print()
# pass 常用于定义空函数/空类
def not_implemented():
pass # TODO: 待实现
class EmptyClass:
pass
# ===== break 跳出嵌套循环的技巧 =====
# 方法1:使用标志变量
print("=== 跳出嵌套循环 ===")
found = False
for i in range(5):
for j in range(5):
if i == 2 and j == 2:
found = True
break
if found:
break
print(f"找到位置: ({i}, {j})")
# 方法2:使用 else + for(Python特有)
for i in range(5):
for j in range(5):
if i == 2 and j == 2:
print(f"找到位置: ({i}, {j})")
break
else:
continue # 内层循环正常结束,继续外层
break # 内层循环被break,跳出外层
4.5 列表推导式
Python 独有的优雅语法,用于简洁地创建列表。
python
# ===== 基本列表推导式 =====
# 传统方式
squares = []
for i in range(1, 11):
squares.append(i ** 2)
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 列表推导式(更简洁)
squares = [i ** 2 for i in range(1, 11)]
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# ===== 带条件的列表推导式 =====
# 1~20中的偶数
evens = [i for i in range(1, 21) if i % 2 == 0]
print(evens) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 带if-else的列表推导式
result = ["偶数" if i % 2 == 0 else "奇数" for i in range(1, 6)]
print(result) # ['奇数', '偶数', '奇数', '偶数', '奇数']
# ===== 嵌套列表推导式 =====
# 矩阵转置
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
print("转置:", transposed) # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
# 笛卡尔积
colors = ["红", "蓝"]
sizes = ["S", "M", "L"]
combos = [(c, s) for c in colors for s in sizes]
print(combos) # [('红', 'S'), ('红', 'M'), ('红', 'L'), ('蓝', 'S'), ('蓝', 'M'), ('蓝', 'L')]
# ===== 字典/集合推导式 =====
# 字典推导式
words = ["apple", "banana", "cherry"]
word_len = {word: len(word) for word in words}
print(word_len) # {'apple': 5, 'banana': 6, 'cherry': 6}
# 集合推导式
nums = [1, 2, 2, 3, 3, 3, 4, 4, 5]
unique = {n for n in nums}
print(unique) # {1, 2, 3, 4, 5}
# ===== 生成器表达式(用圆括号,惰性求值) =====
gen = (i ** 2 for i in range(1, 11))
print(type(gen)) # <class 'generator'>
print(list(gen)) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
五、数据结构
Python 内置了四种核心数据结构,统称为容器类型。
5.1 数据结构概览
| 类型 | 特点 | 有序 | 可变 | 重复 | 示例 |
|---|---|---|---|---|---|
| 列表(list) | 有序集合 | ✅ | ✅ | ✅ | [1, 2, 3] |
| 元组(tuple) | 有序不可变 | ✅ | ❌ | ✅ | (1, 2, 3) |
| 字典(dict) | 键值对 | ✅(3.7+) | ✅ | 键不可 | {"a": 1} |
| 集合(set) | 无序不重复 | ❌ | ✅ | ❌ | {1, 2, 3} |
5.2 列表(List)
列表是 Python 中最常用的数据结构,有序、可变、可重复。
python
# ===== 1. 创建列表 =====
list1 = [1, 2, 3, 4, 5]
list2 = ["苹果", "香蕉", "橙子"]
list3 = [1, "hello", 3.14, True] # 混合类型
list4 = [] # 空列表
list5 = list() # 空列表
list6 = list(range(1, 6)) # [1, 2, 3, 4, 5]
list7 = [0] * 5 # [0, 0, 0, 0, 0]
print(list1) # [1, 2, 3, 4, 5]
print(list3) # [1, 'hello', 3.14, True]
print(list7) # [0, 0, 0, 0, 0]
# ===== 2. 访问元素 =====
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
print(fruits[0]) # 苹果(正索引)
print(fruits[-1]) # 西瓜(负索引,从末尾开始)
print(fruits[-2]) # 葡萄
# 切片 [start:stop:step]
print(fruits[1:4]) # ['香蕉', '橙子', '葡萄'](索引1到3)
print(fruits[:3]) # ['苹果', '香蕉', '橙子'](前3个)
print(fruits[2:]) # ['橙子', '葡萄', '西瓜'](从索引2到末尾)
print(fruits[::2]) # ['苹果', '橙子', '西瓜'](步长为2)
print(fruits[::-1]) # ['西瓜', '葡萄', '橙子', '香蕉', '苹果'](反转)
# ===== 3. 修改元素 =====
fruits[0] = "榴莲"
print(fruits) # ['榴莲', '香蕉', '橙子', '葡萄', '西瓜']
# 切片赋值
fruits[1:3] = ["芒果", "荔枝"]
print(fruits) # ['榴莲', '芒果', '荔枝', '葡萄', '西瓜']
# ===== 4. 添加元素 =====
nums = [1, 2, 3]
nums.append(4) # 末尾添加
print(nums) # [1, 2, 3, 4]
nums.insert(0, 0) # 指定位置插入
print(nums) # [0, 1, 2, 3, 4]
nums.extend([5, 6, 7]) # 扩展列表
print(nums) # [0, 1, 2, 3, 4, 5, 6, 7]
nums += [8, 9] # 等价于 extend
print(nums) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# ===== 5. 删除元素 =====
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
nums.remove(5) # 删除指定值的元素
print(nums) # [0, 1, 2, 3, 4, 6, 7, 8, 9]
del nums[0] # 删除指定索引
print(nums) # [1, 2, 3, 4, 6, 7, 8, 9]
popped = nums.pop() # 弹出末尾元素
print(popped, nums) # 9 [1, 2, 3, 4, 6, 7, 8]
popped = nums.pop(2) # 弹出指定索引
print(popped, nums) # 3 [1, 2, 4, 6, 7, 8]
nums.clear() # 清空列表
print(nums) # []
# ===== 6. 常用方法 =====
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5]
print(f"长度: {len(nums)}") # 9
print(f"最大值: {max(nums)}") # 9
print(f"最小值: {min(nums)}") # 1
print(f"求和: {sum(nums)}") # 36
print(f"计数(5): {nums.count(5)}") # 2
print(f"索引(9): {nums.index(9)}") # 5
# 排序
nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort() # 原地排序(升序)
print(f"升序: {nums}") # [1, 1, 2, 3, 4, 5, 6, 9]
nums.sort(reverse=True) # 降序
print(f"降序: {nums}") # [9, 6, 5, 4, 3, 2, 1, 1]
nums.reverse() # 反转
print(f"反转: {nums}") # [1, 1, 2, 3, 4, 5, 6, 9]
# sorted() 函数(返回新列表,不改原列表)
original = [3, 1, 4, 1, 5]
sorted_list = sorted(original)
print(f"原列表: {original}") # [3, 1, 4, 1, 5]
print(f"排序后: {sorted_list}") # [1, 1, 3, 4, 5]
# ===== 7. 遍历 =====
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
print(fruit, end=" ")
print()
for index, fruit in enumerate(fruits):
print(f"[{index}] {fruit}")
# ===== 8. 列表拷贝 =====
# 浅拷贝
a = [1, 2, 3]
b = a.copy() # 方式1
c = a[:] # 方式2
d = list(a) # 方式3
b[0] = 100
print(a) # [1, 2, 3](a不受影响)
# 注意:嵌套列表的浅拷贝问题
nested = [[1, 2], [3, 4]]
shallow = nested.copy()
shallow[0][0] = 100
print(nested) # [[100, 2], [3, 4]](内部列表被修改!)
# 深拷贝
import copy
nested = [[1, 2], [3, 4]]
deep = copy.deepcopy(nested)
deep[0][0] = 100
print(nested) # [[1, 2], [3, 4]](完全独立)
5.3 元组(Tuple)
元组与列表类似,但不可变(创建后不能修改)。
python
# ===== 1. 创建元组 =====
t1 = (1, 2, 3)
t2 = ("苹果", "香蕉", "橙子")
t3 = () # 空元组
t4 = tuple() # 空元组
t5 = (42,) # 单元素元组(注意逗号!)
t6 = (42) # 这不是元组,是整数42
t7 = 1, 2, 3 # 不加括号也是元组(自动打包)
print(type(t5)) # <class 'tuple'>
print(type(t6)) # <class 'int'>
print(t7) # (1, 2, 3)
# ===== 2. 访问元素 =====
t = ("a", "b", "c", "d", "e")
print(t[0]) # a
print(t[-1]) # e
print(t[1:4]) # ('b', 'c', 'd')
# ===== 3. 元组不可变 =====
# t[0] = "x" # TypeError: 'tuple' object does not support item assignment
# 但元组中的可变元素可以修改
t_mixed = (1, [2, 3], 4)
t_mixed[1].append(5)
print(t_mixed) # (1, [2, 3, 5], 4)
# ===== 4. 元组方法 =====
t = (1, 2, 3, 2, 2, 4)
print(f"长度: {len(t)}")
print(f"计数(2): {t.count(2)}") # 3
print(f"索引(3): {t.index(3)}") # 2
# ===== 5. 元组解包 =====
# 基本解包
a, b, c = (1, 2, 3)
print(a, b, c) # 1 2 3
# 星号解包(收集多余元素)
first, *rest = (1, 2, 3, 4, 5)
print(first, rest) # 1 [2, 3, 4, 5]
*init, last = (1, 2, 3, 4, 5)
print(init, last) # [1, 2, 3, 4] 5
first, *middle, last = (1, 2, 3, 4, 5)
print(first, middle, last) # 1 [2, 3, 4] 5
# 交换变量
a, b = 10, 20
a, b = b, a
print(a, b) # 20 10
# ===== 6. 元组 vs 列表 =====
# 元组更快、更安全(不可变)、可作为字典的键
# 列表更灵活,适合需要修改的场景
5.4 字典(Dict)
字典是键值对的集合,通过键快速查找值。
python
# ===== 1. 创建字典 =====
d1 = {"name": "张三", "age": 25, "city": "北京"}
d2 = {} # 空字典
d3 = dict() # 空字典
d4 = dict(name="李四", age=30) # 使用 dict() 构造
d5 = dict([("name", "王五"), ("age", 28)]) # 从列表创建
d6 = {"a": 1, "b": 2, "c": 3}
print(d1) # {'name': '张三', 'age': 25, 'city': '北京'}
print(d4) # {'name': '李四', 'age': 30}
# ===== 2. 访问元素 =====
person = {"name": "张三", "age": 25, "city": "北京"}
print(person["name"]) # 张三
print(person["age"]) # 25
# print(person["email"]) # KeyError! 键不存在
# 使用 get() 安全访问
print(person.get("email")) # None(键不存在返回None)
print(person.get("email", "未设置")) # 未设置(指定默认值)
print(person.get("name", "未设置")) # 张三
# ===== 3. 添加/修改元素 =====
person["email"] = "zhangsan@qq.com" # 添加新键值对
person["age"] = 26 # 修改已有键的值
print(person)
# update() 批量更新
person.update({"phone": "13800000000", "age": 27})
print(person)
# ===== 4. 删除元素 =====
person = {"name": "张三", "age": 25, "city": "北京", "email": "test@qq.com"}
del person["email"] # 删除指定键
print(person) # {'name': '张三', 'age': 25, 'city': '北京'}
popped = person.pop("city") # 删除并返回值
print(f"删除了: {popped}") # 删除了: 北京
print(person) # {'name': '张三', 'age': 25}
# popitem() 删除最后一个(Python 3.7+ 保证插入顺序)
last = person.popitem()
print(f"删除了: {last}") # ('age', 25)
person.clear() # 清空字典
print(person) # {}
# ===== 5. 遍历字典 =====
scores = {"张三": 90, "李四": 85, "王五": 95}
# 遍历键
print("=== 遍历键 ===")
for name in scores.keys():
print(name, end=" ")
print()
# 遍历值
print("=== 遍历值 ===")
for score in scores.values():
print(score, end=" ")
print()
# 遍历键值对
print("=== 遍历键值对 ===")
for name, score in scores.items():
print(f"{name}: {score}分")
# ===== 6. 字典推导式 =====
# 反转键值
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {v: k for k, v in original.items()}
print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
# 过滤
scores = {"张三": 90, "李四": 55, "王五": 95, "赵六": 48}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed) # {'张三': 90, '王五': 95}
# ===== 7. 统计单词出现次数(经典应用) =====
text = "hello world hello python hello java world"
word_count = {}
for word in text.split():
# 方式1:传统写法
# if word in word_count:
# word_count[word] += 1
# else:
# word_count[word] = 1
# 方式2:使用 get() 更简洁
word_count[word] = word_count.get(word, 0) + 1
# 方式3:使用 collections.Counter(最简洁)
# from collections import Counter
# word_count = Counter(text.split())
for word, count in word_count.items():
print(f" {word}: {count}次")
# hello: 3次
# world: 2次
# python: 1次
# java: 1次
# ===== 8. 嵌套字典 =====
students = {
"张三": {"age": 20, "score": 90, "major": "计算机"},
"李四": {"age": 22, "score": 85, "major": "数学"},
"王五": {"age": 21, "score": 95, "major": "物理"}
}
for name, info in students.items():
print(f"{name}: {info['age']}岁, {info['major']}, {info['score']}分")
5.5 集合(Set)
集合是无序、不重复的元素集合,适合去重和集合运算。
python
# ===== 1. 创建集合 =====
s1 = {1, 2, 3, 4, 5}
s2 = set() # 空集合(注意:{} 是空字典!)
s3 = set([1, 2, 2, 3, 3, 3]) # 从列表创建(自动去重)
s4 = set("hello") # 从字符串创建
print(s1) # {1, 2, 3, 4, 5}
print(s3) # {1, 2, 3}
print(s4) # {'h', 'e', 'l', 'o'}(无序,去重)
# ===== 2. 去重(最常见用途) =====
nums = [1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5]
unique = list(set(nums))
print(unique) # [1, 2, 3, 4, 5](注意顺序可能改变)
# 保持顺序的去重
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5]
seen = set()
unique_ordered = [x for x in nums if not (x in seen or seen.add(x))]
print(unique_ordered) # [3, 1, 4, 5, 9, 2, 6]
# ===== 3. 添加/删除元素 =====
s = {1, 2, 3}
s.add(4) # 添加元素
s.add(2) # 已存在,不会重复添加
print(s) # {1, 2, 3, 4}
s.update([5, 6, 7]) # 批量添加
print(s) # {1, 2, 3, 4, 5, 6, 7}
s.remove(7) # 删除元素(不存在会报错)
s.discard(100) # 删除元素(不存在不报错)
s.pop() # 随机删除一个元素
print(s)
s.clear() # 清空
print(s) # set()
# ===== 4. 集合运算 =====
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
# 交集
print(f"交集: {a & b}") # {4, 5}
print(f"交集: {a.intersection(b)}") # {4, 5}
# 并集
print(f"并集: {a | b}") # {1, 2, 3, 4, 5, 6, 7, 8}
print(f"并集: {a.union(b)}") # {1, 2, 3, 4, 5, 6, 7, 8}
# 差集(a有b没有)
print(f"差集: {a - b}") # {1, 2, 3}
print(f"差集: {a.difference(b)}") # {1, 2, 3}
# 对称差集(只在一个集合中出现的元素)
print(f"对称差集: {a ^ b}") # {1, 2, 3, 6, 7, 8}
print(f"对称差集: {a.symmetric_difference(b)}") # {1, 2, 3, 6, 7, 8}
# 子集/超集判断
c = {1, 2}
print(f"c是a的子集: {c.issubset(a)}}") # True
print(f"a是c的超集: {a.issuperset(c)}") # True
print(f"a和b不相交: {a.isdisjoint({10, 11})}") # True
# ===== 5. 不可变集合 frozenset =====
fs = frozenset([1, 2, 3])
# fs.add(4) # AttributeError! 不可变
print(fs) # frozenset({1, 2, 3})
# frozenset 可以作为字典的键或集合的元素
5.6 数据结构对比总结
python
# ===== 各数据结构的时间复杂度对比 =====
"""
操作 List Tuple Dict Set
索引访问 O(1) O(1) - -
查找(in) O(n) O(n) O(1) O(1)
插入(末尾) O(1) - O(1) O(1)
插入(中间) O(n) - - -
删除 O(n) - O(1) O(1)
"""
# ===== 选择建议 =====
"""
- 需要有序、可变序列 -> List
- 需要有序、不可变序列 -> Tuple
- 需要键值对映射 -> Dict
- 需要去重或集合运算 -> Set
- 需要频繁查找 -> Dict 或 Set(O(1)查找)
"""
六、函数
6.1 函数定义与调用
python
# ===== 基本函数定义 =====
def greet(name):
"""向指定的人打招呼(这是文档字符串)"""
return f"你好,{name}!"
# 调用函数
message = greet("张三")
print(message) # 你好,张三!
# 查看文档字符串
print(greet.__doc__) # 向指定的人打招呼(这是文档字符串)
help(greet)
# ===== 无参数无返回值 =====
def say_hello():
print("Hello, World!")
say_hello() # Hello, World!
# ===== 多返回值 =====
def min_max(numbers):
"""返回最小值和最大值"""
return min(numbers), max(numbers)
minimum, maximum = min_max([3, 1, 4, 1, 5, 9, 2, 6])
print(f"最小值: {minimum}, 最大值: {maximum}") # 最小值: 1, 最大值: 9
# 返回的其实是一个元组
result = min_max([3, 1, 4, 1, 5])
print(result) # (1, 5)
print(type(result)) # <class 'tuple'>
6.2 参数类型
python
# ===== 1. 位置参数 =====
def add(a, b):
return a + b
print(add(3, 5)) # 8
# ===== 2. 关键字参数 =====
def introduce(name, age, city):
print(f"我叫{name},今年{age}岁,来自{city}")
introduce(age=25, city="北京", name="张三") # 关键字参数,顺序无关
introduce("李四", 22, "上海") # 位置参数
# ===== 3. 默认参数 =====
def power(base, exponent=2):
"""计算幂,默认平方"""
return base ** exponent
print(power(5)) # 25(使用默认指数2)
print(power(2, 3)) # 8(指定指数3)
print(power(2, 10)) # 1024
# 注意:默认参数必须放在非默认参数后面
# def wrong(a=1, b): # SyntaxError!
# pass
# 默认参数的陷阱:可变对象作为默认值
def append_to(item, lst=[]): # 危险!
lst.append(item)
return lst
print(append_to(1)) # [1]
print(append_to(2)) # [1, 2](不是[2]!默认列表被共享了)
# 正确写法:使用 None 作为默认值
def append_safe(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
print(append_safe(1)) # [1]
print(append_safe(2)) # [2](每次都是新列表)
# ===== 4. 可变参数 *args =====
def sum_all(*args):
"""接收任意数量的位置参数"""
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
print(sum_all()) # 0
# 解包列表传入
nums = [1, 2, 3, 4, 5]
print(sum_all(*nums)) # 15
# ===== 5. 关键字可变参数 **kwargs =====
def print_info(name, **kwargs):
"""接收任意数量的关键字参数"""
print(f"姓名: {name}")
for key, value in kwargs.items():
print(f" {key}: {value}")
print_info("张三", age=25, city="北京", email="test@qq.com")
# 姓名: 张三
# age: 25
# city: 北京
# email: test@qq.com
# 解包字典传入
info = {"age": 30, "city": "上海"}
print_info("李四", **info)
# ===== 6. 组合使用 =====
def func(a, b, *args, **kwargs):
print(f"位置参数: a={a}, b={b}")
print(f"可变位置参数: {args}")
print(f"关键字参数: {kwargs}")
func(1, 2, 3, 4, 5, name="张三", age=25)
# 位置参数: a=1, b=2
# 可变位置参数: (3, 4, 5)
# 关键字参数: {'name': '张三', 'age': 25}
# ===== 7. 仅关键字参数 (Python 3+) =====
def create_user(name, age, *, role="user", active=True):
"""* 之后的参数必须用关键字传递"""
return {"name": name, "age": age, "role": role, "active": active}
print(create_user("张三", 25)) # 使用默认值
print(create_user("李四", 30, role="admin")) # 指定关键字参数
# create_user("王五", 28, "admin") # TypeError! 必须用关键字
# ===== 8. 仅位置参数 (Python 3.8+) =====
def divide(a, b, /, *, round_result=False):
""" / 之前的参数必须用位置传递 """
result = a / b
return round(result) if round_result else result
print(divide(10, 3)) # 3.3333...
print(divide(10, 3, round_result=True)) # 3
# divide(a=10, b=3) # TypeError! a和b必须用位置传递
6.3 匿名函数(Lambda)
python
# lambda 语法:lambda 参数: 表达式
# 适用于简单的、一次性的函数
# 基本用法
square = lambda x: x ** 2
print(square(5)) # 25
add = lambda a, b: a + b
print(add(3, 5)) # 8
# 条件表达式
max_val = lambda a, b: a if a > b else b
print(max_val(10, 20)) # 20
# ===== 常见应用场景 =====
# 1. 排序的 key
students = [
{"name": "张三", "score": 90},
{"name": "李四", "score": 85},
{"name": "王五", "score": 95}
]
# 按成绩排序
students.sort(key=lambda s: s["score"])
print(students)
# [{'name': '李四', 'score': 85}, {'name': '张三', 'score': 90}, {'name': '王五', 'score': 95}]
# 按成绩降序
students.sort(key=lambda s: s["score"], reverse=True)
print(students)
# 2. map() 函数
nums = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, nums))
print(squared) # [1, 4, 9, 16, 25]
# 3. filter() 函数
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens) # [2, 4]
# 4. sorted() 的 key
words = ["banana", "apple", "cherry", "date"]
words_sorted = sorted(words, key=lambda w: len(w))
print(words_sorted) # ['date', 'apple', 'banana', 'cherry']
# 5. reduce() 函数
from functools import reduce
product = reduce(lambda a, b: a * b, nums)
print(product) # 120 (1*2*3*4*5)
6.4 高阶函数
python
# 高阶函数:接收函数作为参数,或返回函数的函数
# ===== 1. 函数作为参数 =====
def apply(func, value):
"""将函数应用到值上"""
return func(value)
print(apply(lambda x: x * 2, 5)) # 10
print(apply(abs, -10)) # 10
print(apply(str.upper, "hello")) # HELLO
# ===== 2. 函数作为返回值 =====
def make_multiplier(factor):
"""返回一个乘法函数"""
def multiply(x):
return x * factor
return multiply
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
# 使用 lambda 更简洁
def make_multiplier2(factor):
return lambda x: x * factor
# ===== 3. 装饰器(Decorator) =====
import time
def timer(func):
"""计时装饰器"""
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行耗时: {end - start:.4f}秒")
return result
return wrapper
@timer
def slow_function():
"""模拟耗时操作"""
time.sleep(1)
print("函数执行完毕")
slow_function()
# 函数执行完毕
# slow_function 执行耗时: 1.0012秒
# 带参数的装饰器
def repeat(n):
"""重复执行n次"""
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hi(name):
print(f"Hi, {name}!")
say_hi("Python")
# Hi, Python!
# Hi, Python!
# Hi, Python!
# ===== 4. 常用内置高阶函数 =====
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# map:对每个元素应用函数
squared = list(map(lambda x: x ** 2, nums))
print(squared) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# filter:过滤元素
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens) # [2, 4, 6, 8, 10]
# sorted:排序
people = [("张三", 25), ("李四", 20), ("王五", 30)]
sorted_people = sorted(people, key=lambda p: p[1])
print(sorted_people) # [('李四', 20), ('张三', 25), ('王五', 30)]
# any / all
print(any([False, True, False])) # True(至少一个为True)
print(all([True, True, True])) # True(全部为True)
print(all([True, False, True])) # False
6.5 闭包与作用域
python
# ===== 作用域(LEGB规则) =====
# L - Local(局部作用域)
# E - Enclosing(嵌套作用域)
# G - Global(全局作用域)
# B - Built-in(内置作用域)
x = "全局变量" # Global
def outer():
y = "外层函数变量" # Enclosing
def inner():
z = "内层函数变量" # Local
print(x) # 全局变量
print(y) # 外层函数变量
print(z) # 内层函数变量
inner()
outer()
# ===== global 关键字 =====
count = 0
def increment():
global count # 声明使用全局变量
count += 1
increment()
increment()
increment()
print(count) # 3
# ===== nonlocal 关键字 =====
def make_counter():
count = 0 # Enclosing 变量
def counter():
nonlocal count # 声明使用外层变量(非全局)
count += 1
return count
return counter
c = make_counter()
print(c()) # 1
print(c()) # 2
print(c()) # 3
# ===== 闭包 =====
# 闭包 = 函数 + 引用的外层变量
def make_adder(x):
def adder(y):
return x + y # x 被闭包引用
return adder
add5 = make_adder(5)
add10 = make_adder(10)
print(add5(3)) # 8
print(add10(3)) # 13
# 查看闭包引用的变量
print(add5.__closure__[0].cell_contents) # 5
6.6 递归
python
# ===== 1. 阶乘 =====
def factorial(n):
"""计算n的阶乘"""
if n <= 1: # 基线条件(终止条件)
return 1
return n * factorial(n - 1) # 递归调用
print(f"5! = {factorial(5)}") # 120
print(f"10! = {factorial(10)}") # 3628800
# ===== 2. 斐波那契数列 =====
def fib(n):
"""第n个斐波那契数"""
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
# 打印前10个斐波那契数
print("斐波那契数列:", [fib(i) for i in range(10)])
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
# 优化:使用缓存避免重复计算
from functools import lru_cache
@lru_cache(maxsize=None)
def fib_optimized(n):
if n <= 1:
return n
return fib_optimized(n - 1) + fib_optimized(n - 2)
print(f"fib(100) = {fib_optimized(100)}") # 快速计算
# ===== 3. 汉诺塔 =====
def hanoi(n, source, target, auxiliary):
"""汉诺塔"""
if n == 1:
print(f"移动盘子 {n}: {source} -> {target}")
else:
hanoi(n - 1, source, auxiliary, target)
print(f"移动盘子 {n}: {source} -> {target}")
hanoi(n - 1, auxiliary, target, source)
hanoi(3, "A", "C", "B")
# 移动盘子 1: A -> C
# 移动盘子 2: A -> B
# 移动盘子 1: C -> B
# 移动盘子 3: A -> C
# 移动盘子 1: B -> A
# 移动盘子 2: B -> C
# 移动盘子 1: A -> C
七、面向对象编程(OOP)
7.1 类与对象
python
# ===== 定义学生类 =====
class Student:
# 类变量(所有实例共享)
school = "清华大学"
count = 0
# 构造方法(初始化方法)
def __init__(self, name, age, student_id):
# 实例变量
self.name = name
self.age = age
self.student_id = student_id
Student.count += 1 # 类变量计数
# 实例方法
def study(self, subject):
print(f"{self.name}正在学习{subject}")
def introduce(self):
print(f"大家好,我是{self.name},今年{self.age}岁,学号{self.student_id},就读于{Student.school}")
# 类方法(用 @classmethod 装饰)
@classmethod
def get_count(cls):
"""获取学生总数"""
return cls.count
# 静态方法(用 @staticmethod 装饰)
@staticmethod
def is_valid_age(age):
"""验证年龄是否合法"""
return 0 < age < 150
# 字符串表示
def __str__(self):
return f"Student(name={self.name}, age={self.age}, id={self.student_id})"
# 开发者字符串表示
def __repr__(self):
return f"Student('{self.name}', {self.age}, '{self.student_id}')"
# 析构方法(对象被回收时调用)
def __del__(self):
pass # 一般不需要手动实现
# ===== 创建对象 =====
s1 = Student("张三", 20, "2024001")
s2 = Student("李四", 22, "2024002")
# 调用实例方法
s1.introduce() # 大家好,我是张三,今年20岁,学号2024001,就读于清华大学
s2.study("Python") # 李四正在学习Python
# 访问变量
print(s1.name) # 张三(实例变量)
print(Student.school) # 清华大学(类变量)
print(s2.school) # 清华大学(也可以通过实例访问)
# 类方法和静态方法
print(f"学生总数: {Student.get_count()}") # 2
print(f"年龄25是否合法: {Student.is_valid_age(25)}") # True
# 字符串表示
print(s1) # Student(name=张三, age=20, id=2024001)
print(repr(s1)) # Student('张三', 20, '2024001')
# 动态添加属性(Python特有)
s1.phone = "13800000000"
print(s1.phone) # 13800000000
# print(s2.phone) # AttributeError! s2没有phone属性
7.2 封装
Python 通过命名约定实现封装,而非强制访问控制。
python
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner # 公有属性
self._type = "储蓄卡" # 受保护属性(约定,单下划线)
self.__balance = balance # 私有属性(双下划线,名称重整)
# 公有方法
def deposit(self, amount):
"""存款"""
if amount > 0:
self.__balance += amount
print(f"{self.owner} 存入 {amount},余额: {self.__balance}")
else:
print("存款金额必须大于0")
def withdraw(self, amount):
"""取款"""
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"{self.owner} 取出 {amount},余额: {self.__balance}")
elif amount > self.__balance:
print(f"余额不足!当前余额: {self.__balance}")
else:
print("取款金额必须大于0")
# 提供公有方法访问私有属性(getter)
def get_balance(self):
return self.__balance
# setter
def set_balance(self, balance):
if balance >= 0:
self.__balance = balance
else:
print("余额不能为负数")
account = BankAccount("张三", 1000)
account.deposit(500) # 张三 存入 500,余额: 1500
account.withdraw(200) # 张三 取出 200,余额: 1300
account.withdraw(5000) # 余额不足!当前余额: 1300
# 访问属性
print(account.owner) # 张三(公有,可直接访问)
print(account._type) # 储蓄卡(受保护,可以访问但不建议)
# print(account.__balance) # AttributeError! 私有属性不能直接访问
# 通过 getter 访问
print(account.get_balance()) # 1300
# 名称重整:实际上 __balance 被重命名为 _BankAccount__balance
print(account._BankAccount__balance) # 1300(可以访问,但不推荐)
# ===== 使用 property 装饰器(推荐的封装方式) =====
class Temperature:
def __init__(self, celsius=0):
self.celsius = celsius # 通过 setter 设置
@property
def celsius(self):
"""获取摄氏温度"""
return self._celsius
@celsius.setter
def celsius(self, value):
"""设置摄氏温度,自动验证"""
if value < -273.15:
raise ValueError("温度不能低于绝对零度 (-273.15°C)")
self._celsius = value
@property
def fahrenheit(self):
"""华氏温度(只读属性)"""
return self._celsius * 9 / 5 + 32
temp = Temperature(25)
print(f"摄氏: {temp.celsius}°C") # 25°C
print(f"华氏: {temp.fahrenheit}°F") # 77.0°F
temp.celsius = 30 # 通过 setter 设置
print(f"摄氏: {temp.celsius}°C") # 30°C
# temp.celsius = -300 # ValueError!
7.3 继承
python
# ===== 父类 =====
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
print(f"Animal.__init__: {name}")
def eat(self):
print(f"{self.name}正在吃东西")
def sleep(self):
print(f"{self.name}正在睡觉")
def speak(self):
print(f"{self.name}发出了声音")
def __str__(self):
return f"Animal(name={self.name}, age={self.age})"
# ===== 单继承 =====
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age) # 调用父类构造方法
self.breed = breed
print(f"Dog.__init__: 品种={breed}")
def bark(self):
print(f"{self.name}({self.breed})在汪汪叫")
# 方法重写
def speak(self):
print(f"{self.name}在汪汪叫")
def fetch(self):
print(f"{self.name}在接飞盘")
def __str__(self):
return f"Dog(name={self.name}, age={self.age}, breed={self.breed})"
# ===== 多继承 =====
class Swimmable:
def swim(self):
print(f"{self.name}在游泳")
class Flyable:
def fly(self):
print(f"{self.name}在飞")
# 多继承:同时继承 Animal、Swimmable、Flyable
class Duck(Animal, Swimmable, Flyable):
def __init__(self, name, age):
super().__init__(name, age)
def speak(self):
print(f"{self.name}在嘎嘎叫")
# ===== 测试继承 =====
print("=== 单继承 ===")
dog = Dog("旺财", 3, "金毛")
dog.eat() # 继承自Animal
dog.sleep() # 继承自Animal
dog.speak() # 重写的方法:旺财在汪汪叫
dog.bark() # Dog特有方法
dog.fetch() # Dog特有方法
print(dog) # Dog(name=旺财, age=3, breed=金毛)
print("\n=== 多继承 ===")
duck = Duck("唐老鸭", 5)
duck.eat() # 继承自Animal
duck.swim() # 继承自Swimmable
duck.fly() # 继承自Flyable
duck.speak() # 重写的方法:唐老鸭在嘎嘎叫
# ===== isinstance / issubclass =====
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True(Dog是Animal的子类)
print(isinstance(duck, Animal)) # True
print(issubclass(Dog, Animal)) # True
print(issubclass(Duck, Flyable)) # True
# ===== MRO(方法解析顺序) =====
print(Duck.__mro__)
# (<class 'Duck'>, <class 'Animal'>, <class 'Swimmable'>, <class 'Flyable'>, <class 'object'>)
7.4 多态
python
# ===== 多态示例 =====
class Shape:
def area(self):
return 0
def draw(self):
print("绘制一个图形")
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
def draw(self):
print(f"绘制一个半径为 {self.radius} 的圆形")
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def draw(self):
print(f"绘制一个 {self.width}x{self.height} 的矩形")
class Triangle(Shape):
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
def draw(self):
print(f"绘制一个底{self.base}高{self.height}的三角形")
# 多态:同一个函数处理不同类型的对象
def print_shape_info(shape):
"""打印图形信息(多态)"""
shape.draw()
print(f"面积: {shape.area():.2f}")
# 创建不同形状
shapes = [
Circle(5),
Rectangle(4, 6),
Triangle(3, 8)
]
# 同一个函数调用,不同的行为表现
for shape in shapes:
print_shape_info(shape)
print()
# 输出:
# 绘制一个半径为 5 的圆形
# 面积: 78.54
#
# 绘制一个 4x6 的矩形
# 面积: 24.00
#
# 绘制一个底3高8的三角形
# 面积: 12.00
# ===== 鸭子类型(Duck Typing)=====
# Python 的多态不依赖继承,只要对象有相同的方法即可
class Parrot:
def speak(self):
print("鹦鹉在说话")
class Cat:
def speak(self):
print("猫在喵喵叫")
def make_speak(animal):
"""不关心类型,只要有 speak 方法就行"""
animal.speak()
make_speak(Parrot()) # 鹦鹉在说话
make_speak(Cat()) # 猫在喵喵叫
# 这就是 Python 的"鸭子类型":如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子
7.5 魔术方法(特殊方法)
python
class Vector:
"""二维向量类,演示常用魔术方法"""
def __init__(self, x, y):
self.x = x
self.y = y
# 字符串表示
def __str__(self):
return f"Vector({self.x}, {self.y})"
def __repr__(self):
return f"Vector({self.x}, {self.y})"
# 加法: v1 + v2
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
# 减法: v1 - v2
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
# 乘法: v1 * scalar
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
# 相等: v1 == v2
def __eq__(self, other):
return self.x == other.x and self.y == other.y
# 小于: v1 < v2
def __lt__(self, other):
return self.length() < other.length()
# 长度: len(v)
def __len__(self):
return 2
# 布尔值: bool(v)
def __bool__(self):
return self.x != 0 or self.y != 0
# 迭代: for i in v
def __iter__(self):
return iter([self.x, self.y])
# 索引访问: v[0]
def __getitem__(self, index):
if index == 0:
return self.x
elif index == 1:
return self.y
raise IndexError("Vector index out of range")
# 索引赋值: v[0] = 10
def __setitem__(self, index, value):
if index == 0:
self.x = value
elif index == 1:
self.y = value
else:
raise IndexError("Vector index out of range")
# 包含: 5 in v
def __contains__(self, item):
return item in (self.x, self.y)
# 辅助方法
def length(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
# ===== 测试魔术方法 =====
v1 = Vector(3, 4)
v2 = Vector(1, 2)
print(v1) # Vector(3, 4) -> __str__
print(repr(v1)) # Vector(3, 4) -> __repr__
# 运算符重载
v3 = v1 + v2
print(f"v1 + v2 = {v3}") # Vector(4, 6)
v4 = v1 - v2
print(f"v1 - v2 = {v4}") # Vector(2, 2)
v5 = v1 * 3
print(f"v1 * 3 = {v5}") # Vector(9, 12)
# 比较
print(f"v1 == v2: {v1 == v2}") # False -> __eq__
print(f"v1 > v2: {v1 > v2}") # True -> __lt__(反过来)
# 其他魔术方法
print(f"len(v1): {len(v1)}") # 2 -> __len__
print(f"bool(v1): {bool(v1)}") # True -> __bool__
print(f"v1[0]: {v1[0]}") # 3 -> __getitem__
print(f"3 in v1: {3 in v1}") # True -> __contains__
for component in v1: # -> __iter__
print(component, end=" ") # 3 4
print()
v1[0] = 10 # -> __setitem__
print(f"修改后: {v1}") # Vector(10, 4)
八、异常处理
8.1 异常体系
Python 中所有异常都是 BaseException 的子类:
BaseException
├── SystemExit # sys.exit() 触发
├── KeyboardInterrupt # Ctrl+C 中断
├── GeneratorExit # 生成器关闭
└── Exception # 所有常规异常的基类
├── StopIteration
├── ArithmeticError
│ ├── ZeroDivisionError # 除零错误
│ └── OverflowError
├── LookupError
│ ├── IndexError # 索引越界
│ └── KeyError # 键不存在
├── TypeError # 类型错误
├── ValueError # 值错误
├── AttributeError # 属性不存在
├── FileNotFoundError # 文件不存在
├── ImportError # 导入失败
└── ...
8.2 异常处理机制
python
# ===== 1. try-except =====
try:
num = int("abc") # ValueError
except ValueError:
print("捕获到值错误异常")
print("程序继续执行...")
# ===== 2. try-except-else =====
try:
num = int("123")
except ValueError:
print("转换失败")
else:
print(f"转换成功: {num}") # 没有异常时执行
# ===== 3. try-except-finally =====
try:
f = open("test.txt", "w")
f.write("Hello")
except IOError:
print("文件操作失败")
finally:
f.close() # 无论是否异常都会执行
print("文件已关闭")
# ===== 4. 捕获多种异常 =====
try:
# 可能产生多种异常的代码
value = int(input("输入数字: "))
result = 10 / value
print(f"结果: {result}")
except ValueError:
print("输入的不是有效数字")
except ZeroDivisionError:
print("不能除以零")
except Exception as e:
print(f"其他异常: {e}")
# ===== 5. 捕获异常信息 =====
try:
nums = [1, 2, 3]
print(nums[10])
except IndexError as e:
print(f"异常类型: {type(e).__name__}") # IndexError
print(f"异常信息: {e}") # list index out of range
# ===== 6. 同时捕获多种异常 =====
try:
# ...
pass
except (ValueError, TypeError, KeyError) as e:
print(f"捕获到异常: {type(e).__name__}: {e}")
# ===== 7. raise 抛出异常 =====
def check_age(age):
if age < 0 or age > 150:
raise ValueError(f"年龄必须在 0~150 之间,当前: {age}")
return age
try:
check_age(-5)
except ValueError as e:
print(f"捕获: {e}")
# ===== 8. 异常链 raise from =====
try:
int("abc")
except ValueError as e:
raise RuntimeError("数据处理失败") from e # 异常链
# ===== 9. 自定义异常 =====
class InsufficientFundsError(Exception):
"""余额不足异常"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(
f"余额不足!当前余额: {balance},取款金额: {amount}"
)
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
return self.balance
account = BankAccount(1000)
try:
account.withdraw(1500)
except InsufficientFundsError as e:
print(f"捕获自定义异常: {e}")
print(f"余额: {e.balance}, 取款: {e.amount}")
# ===== 10. assert 断言 =====
def divide(a, b):
assert b != 0, "除数不能为零" # 条件为False时抛出 AssertionError
return a / b
try:
divide(10, 0)
except AssertionError as e:
print(f"断言失败: {e}")
8.3 自定义异常体系
python
# ===== 自定义异常层次结构 =====
class AppError(Exception):
"""应用程序基础异常"""
pass
class DatabaseError(AppError):
"""数据库异常"""
pass
class ConnectionError(DatabaseError):
"""连接异常"""
pass
class QueryError(DatabaseError):
"""查询异常"""
pass
class ValidationError(AppError):
"""数据验证异常"""
def __init__(self, field, message):
self.field = field
self.message = message
super().__init__(f"验证失败 [{field}]: {message}")
# 使用
def validate_email(email):
if "@" not in email:
raise ValidationError("email", "邮箱格式不正确")
try:
validate_email("invalid-email")
except ValidationError as e:
print(f"验证错误: {e}")
print(f"错误字段: {e.field}")
# 捕获父类异常可以捕获所有子类异常
try:
raise ConnectionError("数据库连接超时")
except DatabaseError as e: # 捕获父类,也能捕获子类
print(f"数据库错误: {e}")
except AppError as e:
print(f"应用错误: {e}")
九、文件操作
9.1 文件读写
python
# ===== 1. 写入文件 =====
# 方式1:传统方式(需要手动关闭)
f = open("test.txt", "w", encoding="utf-8")
f.write("Hello, Python!\n")
f.write("这是第二行。\n")
f.close()
# 方式2:with 语句(推荐,自动关闭文件)
with open("test.txt", "w", encoding="utf-8") as f:
f.write("Hello, Python!\n")
f.write("这是第二行。\n")
# 离开 with 块后自动关闭
# 写入多行
lines = ["第一行\n", "第二行\n", "第三行\n"]
with open("test.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
# ===== 2. 读取文件 =====
# 读取全部内容
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 逐行读取
with open("test.txt", "r", encoding="utf-8") as f:
for line in f:
print(line, end="") # line 已包含换行符
# 读取所有行为列表
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines) # ['第一行\n', '第二行\n', '第三行\n']
# readline() 逐行读取
with open("test.txt", "r", encoding="utf-8") as f:
line1 = f.readline()
line2 = f.readline()
print(line1, end="")
print(line2, end="")
# ===== 3. 文件模式 =====
"""
模式 说明
'r' 读(默认),文件不存在则报错
'w' 写,文件不存在则创建,存在则覆盖
'a' 追加,文件不存在则创建
'r+' 读写
'w+' 写读(覆盖)
'a+' 追加读写
'b' 二进制模式(如 'rb', 'wb')
't' 文本模式(默认)
"""
# 二进制文件操作(图片等)
with open("source.jpg", "rb") as src, open("copy.jpg", "wb") as dst:
dst.write(src.read())
print("图片复制完成")
# ===== 4. 追加写入 =====
with open("test.txt", "a", encoding="utf-8") as f:
f.write("这是追加的内容\n")
# ===== 5. 文件指针 =====
with open("test.txt", "r+", encoding="utf-8") as f:
# 读取前5个字符
print(f.read(5))
# 获取当前位置
print(f"当前位置: {f.tell()}")
# 移动指针到开头
f.seek(0)
print(f"重置后位置: {f.tell()}")
# 重新读取
print(f.read(10))
9.2 文件与目录操作
python
import os
import shutil
# ===== 1. 路径操作 =====
# 当前工作目录
print(f"当前目录: {os.getcwd()}")
# 拼接路径(推荐,跨平台)
path = os.path.join("folder", "subfolder", "file.txt")
print(f"拼接路径: {path}") # folder/subfolder/file.txt(Linux)或 folder\subfolder\file.txt(Windows)
# 路径分解
print(f"目录: {os.path.dirname(path)}") # folder/subfolder
print(f"文件名: {os.path.basename(path)}") # file.txt
print(f"扩展名: {os.path.splitext(path)}") # ('folder/subfolder/file', '.txt')
# 路径是否存在
print(f"路径存在: {os.path.exists('test.txt')}")
print(f"是文件: {os.path.isfile('test.txt')}")
print(f"是目录: {os.path.isdir('test.txt')}")
# ===== 2. 文件操作 =====
# 创建目录
os.makedirs("test_dir/sub_dir", exist_ok=True)
# 创建空文件
with open("test_dir/file.txt", "w") as f:
f.write("test")
# 重命名
os.rename("test_dir/file.txt", "test_dir/renamed.txt")
# 删除文件
os.remove("test_dir/renamed.txt")
# 删除空目录
os.rmdir("test_dir/sub_dir")
# 删除目录树
shutil.rmtree("test_dir")
# ===== 3. 遍历目录 =====
# 方法1:os.listdir
for item in os.listdir("."):
print(item, end=" ")
print()
# 方法2:os.walk(递归遍历)
for root, dirs, files in os.walk("."):
for f in files:
print(os.path.join(root, f))
# 方法3:pathlib(推荐,Python 3.4+)
from pathlib import Path
# 创建 Path 对象
p = Path(".")
# 列出当前目录下的所有 .py 文件
for py_file in p.glob("**/*.py"):
print(py_file)
# Path 的常用操作
p = Path("folder/sub/file.txt")
print(p.parent) # folder/sub
print(p.name) # file.txt
print(p.stem) # file
print(p.suffix) # .txt
# 创建目录
Path("new_folder").mkdir(exist_ok=True)
# 读写文件(Path 对象的方法)
p = Path("test.txt")
p.write_text("Hello, Path!", encoding="utf-8")
content = p.read_text(encoding="utf-8")
print(content)
9.3 JSON 文件操作
python
import json
# ===== Python 对象 -> JSON 字符串 =====
data = {
"name": "张三",
"age": 25,
"hobbies": ["读书", "编程", "旅行"],
"married": False,
"address": {
"city": "北京",
"zip": "100000"
}
}
# 序列化为 JSON 字符串
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
# 写入 JSON 文件
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# ===== JSON 字符串 -> Python 对象 =====
# 反序列化
parsed = json.loads(json_str)
print(parsed["name"]) # 张三
print(parsed["hobbies"]) # ['读书', '编程', '旅行']
# 从 JSON 文件读取
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded["address"]["city"]) # 北京
# ===== 自定义序列化 =====
from datetime import datetime
class Person:
def __init__(self, name, birthday):
self.name = name
self.birthday = birthday
def to_dict(self):
return {
"name": self.name,
"birthday": self.birthday.strftime("%Y-%m-%d")
}
person = Person("张三", datetime(2000, 5, 15))
json_str = json.dumps(person.to_dict(), ensure_ascii=False)
print(json_str) # {"name": "张三", "birthday": "2000-05-15"}
9.4 CSV 文件操作
python
import csv
# ===== 写入 CSV =====
data = [
["姓名", "年龄", "城市"],
["张三", 25, "北京"],
["李四", 30, "上海"],
["王五", 28, "广州"]
]
with open("data.csv", "w", encoding="utf-8-sig", newline="") as f:
writer = csv.writer(f)
writer.writerows(data)
# 使用 DictWriter
data_dict = [
{"姓名": "张三", "年龄": 25, "城市": "北京"},
{"姓名": "李四", "年龄": 30, "城市": "上海"},
]
with open("data2.csv", "w", encoding="utf-8-sig", newline="") as f:
fieldnames = ["姓名", "年龄", "城市"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data_dict)
# ===== 读取 CSV =====
# 使用 reader
with open("data.csv", "r", encoding="utf-8-sig") as f:
reader = csv.reader(f)
for row in reader:
print(row)
# ['姓名', '年龄', '城市']
# ['张三', '25', '北京']
# ['李四', '30', '上海']
# ['王五', '28', '广州']
# 使用 DictReader
with open("data.csv", "r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['姓名']}, {row['年龄']}岁, {row['城市']}")
十、模块与包
10.1 模块
模块就是一个 .py 文件,用于组织代码。
python
# ===== math_utils.py(自定义模块) =====
"""数学工具模块"""
PI = 3.141592653589793
def add(a, b):
"""加法"""
return a + b
def multiply(a, b):
"""乘法"""
return a * b
class Calculator:
"""计算器类"""
def power(self, base, exp):
return base ** exp
# 模块内测试代码(仅在直接运行时执行,被导入时不执行)
if __name__ == "__main__":
print(f"1 + 2 = {add(1, 2)}")
print(f"3 * 4 = {multiply(3, 4)}")
python
# ===== main.py(导入模块) =====
# 方式1:导入整个模块
import math_utils
print(math_utils.add(1, 2)) # 3
print(math_utils.PI) # 3.141592653589793
# 方式2:导入特定内容
from math_utils import add, multiply, Calculator
print(add(3, 5)) # 8
calc = Calculator()
print(calc.power(2, 10)) # 1024
# 方式3:导入并设置别名
import math_utils as mu
print(mu.multiply(3, 4)) # 12
# 方式4:导入所有内容(不推荐,可能命名冲突)
# from math_utils import *
# ===== 标准库模块示例 =====
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
print(math.ceil(3.2)) # 4
print(math.floor(3.8)) # 3
import random
print(random.randint(1, 100)) # 随机整数
print(random.choice(["苹果", "香蕉"])) # 随机选择
print(random.shuffle([1, 2, 3, 4, 5])) # 打乱列表(原地修改)
import datetime
now = datetime.datetime.now()
print(now) # 2026-08-10 15:30:00.123456
print(now.strftime("%Y年%m月%d日 %H:%M:%S"))
import os
print(os.getcwd()) # 当前工作目录
10.2 包
包是包含 __init__.py 的目录,用于组织多个模块。
my_package/
├── __init__.py # 包初始化文件
├── math_tools/
│ ├── __init__.py
│ ├── basic.py # 基础数学工具
│ └── advanced.py # 高级数学工具
├── string_tools/
│ ├── __init__.py
│ └── formatter.py # 字符串格式化工具
└── utils.py # 通用工具
python
# ===== my_package/__init__.py =====
"""我的工具包"""
__version__ = "1.0.0"
# ===== my_package/math_tools/basic.py =====
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# ===== my_package/math_tools/advanced.py =====
import math
def sqrt(n):
return math.sqrt(n)
def power(base, exp):
return base ** exp
# ===== my_package/string_tools/formatter.py =====
def capitalize(text):
return text.capitalize()
def reverse(text):
return text[::-1]
# ===== 使用包 =====
# 导入包中的模块
from my_package.math_tools.basic import add, subtract
from my_package.math_tools.advanced import sqrt
from my_package.string_tools.formatter import capitalize
print(add(1, 2)) # 3
print(sqrt(16)) # 4.0
print(capitalize("hello")) # Hello
# 导入整个模块
import my_package.math_tools.basic as basic
print(basic.subtract(10, 3)) # 7
# 使用包的版本号
import my_package
print(my_package.__version__) # 1.0.0
10.3 __name__ 与 __main__
python
# ===== 每个模块都有 __name__ 属性 =====
# 当模块被直接运行时,__name__ == "__main__"
# 当模块被导入时,__name__ == 模块名
# module.py
def greet():
print("Hello!")
if __name__ == "__main__":
# 这部分代码只在直接运行 module.py 时执行
# 被 import 时不执行
greet()
print("这是测试代码")
十一、常用标准库
11.1 os - 操作系统接口
python
import os
# 环境变量
print(os.environ.get("PATH")) # 获取环境变量
os.environ["MY_VAR"] = "123" # 设置环境变量
# 系统信息
print(os.name) # 'nt' (Windows) / 'posix' (Linux/macOS)
print(os.cpu_count()) # CPU 核心数
# 执行系统命令
result = os.popen("echo Hello").read()
print(result.strip()) # Hello
# 路径操作
print(os.path.abspath(".")) # 绝对路径
print(os.path.exists("test.txt")) # 是否存在
print(os.path.join("a", "b", "c")) # 拼接路径
11.2 sys - 系统相关
python
import sys
# Python 版本
print(sys.version) # 3.12.0 (...)
print(sys.version_info) # sys.version_info(major=3, minor=12, ...)
# 平台
print(sys.platform) # 'win32' / 'linux' / 'darwin'
# 模块搜索路径
print(sys.path) # 模块搜索路径列表
# 命令行参数
print(sys.argv) # ['script.py', 'arg1', 'arg2']
# 递归限制
print(sys.getrecursionlimit()) # 1000
sys.setrecursionlimit(2000)
# 退出
# sys.exit(0) # 正常退出
# sys.exit(1) # 异常退出
11.3 datetime - 日期时间
python
from datetime import datetime, date, time, timedelta
# ===== 当前时间 =====
now = datetime.now()
print(now) # 2026-08-10 15:30:00.123456
today = date.today()
print(today) # 2026-08-10
# ===== 创建指定日期 =====
dt = datetime(2026, 1, 15, 10, 30, 0)
print(dt) # 2026-01-15 10:30:00
d = date(2026, 1, 15)
t = time(10, 30, 0)
print(d, t)
# ===== 格式化 =====
# datetime -> 字符串
formatted = now.strftime("%Y年%m月%d日 %H:%M:%S")
print(formatted) # 2026年08月10日 15:30:00
formatted2 = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted2) # 2026-08-10 15:30:00
# 字符串 -> datetime
parsed = datetime.strptime("2026-01-15 10:30:00", "%Y-%m-%d %H:%M:%S")
print(parsed) # 2026-01-15 10:30:00
"""
常用格式化符号:
%Y 四位年份 %m 月份(01-12)
%d 日(01-31) %H 时(00-23)
%M 分(00-59) %S 秒(00-59)
%A 星期名称 %B 月份名称
%w 星期(0-6) %j 年内天数
"""
# ===== 时间差 =====
date1 = datetime(2026, 1, 1)
date2 = datetime(2026, 8, 10)
diff = date2 - date1
print(f"相差: {diff.days}天") # 相差: 221天
# timedelta 运算
tomorrow = now + timedelta(days=1)
last_week = now - timedelta(weeks=1)
two_hours_later = now + timedelta(hours=2)
print(f"明天: {tomorrow}")
print(f"上周: {last_week}")
# ===== 时间戳 =====
timestamp = now.timestamp()
print(f"时间戳: {timestamp}")
from_timestamp = datetime.fromtimestamp(timestamp)
print(f"从时间戳恢复: {from_timestamp}")
# ===== ISO 格式 =====
iso_str = now.isoformat()
print(f"ISO格式: {iso_str}") # 2026-08-10T15:30:00.123456
11.4 collections - 高级容器
python
from collections import Counter, defaultdict, OrderedDict, deque, namedtuple
# ===== 1. Counter - 计数器 =====
text = "hello world hello python"
counter = Counter(text.split())
print(counter) # Counter({'hello': 2, 'world': 1, 'python': 1})
# 最常见的元素
print(counter.most_common(1)) # [('hello', 2)]
# 计数运算
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2) # Counter({'a': 4, 'b': 3})
print(c1 - c2) # Counter({'a': 2})
# ===== 2. defaultdict - 带默认值的字典 =====
# 传统方式
word_count = {}
for word in text.split():
if word not in word_count:
word_count[word] = 0
word_count[word] += 1
# 使用 defaultdict
word_count = defaultdict(int) # 默认值为0
for word in text.split():
word_count[word] += 1
print(dict(word_count))
# 分组
students = [("张三", 90), ("李四", 85), ("张三", 88), ("李四", 92)]
grouped = defaultdict(list)
for name, score in students:
grouped[name].append(score)
print(dict(grouped)) # {'张三': [90, 88], '李四': [85, 92]}
# ===== 3. OrderedDict - 有序字典 =====
# Python 3.7+ 普通 dict 也保持插入顺序
# OrderedDict 额外支持 move_to_end, popitem 等
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od["c"] = 3
od.move_to_end("a") # 将a移到末尾
print(od) # OrderedDict([('b', 2), ('c', 3), ('a', 1)])
# ===== 4. deque - 双端队列 =====
dq = deque([1, 2, 3])
dq.appendleft(0) # 左侧添加
dq.append(4) # 右侧添加
print(dq) # deque([0, 1, 2, 3, 4])
dq.popleft() # 左侧弹出
dq.pop() # 右侧弹出
print(dq) # deque([1, 2, 3])
# 固定长度(自动丢弃旧元素)
dq = deque(maxlen=3)
for i in range(5):
dq.append(i)
print(dq)
# deque([0], maxlen=3)
# deque([0, 1], maxlen=3)
# deque([0, 1, 2], maxlen=3)
# deque([1, 2, 3], maxlen=3)
# deque([2, 3, 4], maxlen=3)
# ===== 5. namedtuple - 命名元组 =====
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y) # 3 4(通过名称访问)
print(p[0], p[1]) # 3 4(通过索引访问)
print(p._asdict()) # {'x': 3, 'y': 4}
# 实际应用
Student = namedtuple("Student", ["name", "age", "score"])
students = [
Student("张三", 20, 90),
Student("李四", 22, 85),
]
for s in students:
print(f"{s.name}: {s.age}岁, {s.score}分")
11.5 itertools - 迭代工具
python
import itertools
# ===== 1. count - 无限计数 =====
for i in itertools.count(10, 2): # 从10开始,步长2
if i > 20:
break
print(i, end=" ") # 10 12 14 16 18 20
print()
# ===== 2. cycle - 无限循环 =====
# for item in itertools.cycle("AB"):
# print(item) # A B A B A B ...(无限循环)
# ===== 3. repeat - 重复 =====
print(list(itertools.repeat("Hi", 3))) # ['Hi', 'Hi', 'Hi']
# ===== 4. chain - 连接多个迭代器 =====
combined = itertools.chain([1, 2], [3, 4], [5, 6])
print(list(combined)) # [1, 2, 3, 4, 5, 6]
# ===== 5. combinations / permutations =====
# 排列(有顺序)
perms = itertools.permutations("ABC", 2)
print(list(perms))
# [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
# 组合(无顺序)
combs = itertools.combinations("ABC", 2)
print(list(combs))
# [('A', 'B'), ('A', 'C'), ('B', 'C')]
# 带替换的组合
combs_replacement = itertools.combinations_with_replacement("ABC", 2)
print(list(combs_replacement))
# [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
# ===== 6. product - 笛卡尔积 =====
colors = ["红", "蓝"]
sizes = ["S", "M", "L"]
for color, size in itertools.product(colors, sizes):
print(f"({color}, {size})", end=" ")
# (红, S) (红, M) (红, L) (蓝, S) (蓝, M) (蓝, L)
print()
# ===== 7. groupby - 分组 =====
data = [("A", 1), ("A", 2), ("B", 3), ("B", 4), ("C", 5)]
for key, group in itertools.groupby(data, key=lambda x: x[0]):
print(f"{key}: {list(group)}")
# A: [('A', 1), ('A', 2)]
# B: [('B', 3), ('B', 4)]
# C: [('C', 5)]
11.6 其他常用标准库速览
python
# ===== math - 数学函数 =====
import math
print(math.factorial(5)) # 120(阶乘)
print(math.gcd(12, 18)) # 6(最大公约数)
print(math.log(100, 10)) # 2.0(对数)
print(math.sin(math.pi / 2)) # 1.0(正弦)
# ===== random - 随机数 =====
import random
print(random.random()) # 0~1 随机浮点数
print(random.randint(1, 100)) # 随机整数
print(random.choice([1, 2, 3])) # 随机选择
print(random.sample(range(100), 5)) # 随机采样5个
items = [1, 2, 3, 4, 5]
random.shuffle(items) # 打乱
print(items)
# ===== re - 正则表达式 =====
import re
# 查找
print(re.findall(r"\d+", "电话: 13800000000, 邮编: 100000"))
# ['13800000000', '100000']
# 替换
print(re.sub(r"\d", "*", "abc123def456")) # abc***def***
# 分割
print(re.split(r"[,;\s]+", "a, b; c d")) # ['a', 'b', 'c', 'd']
# 匹配邮箱
email_pattern = r"[\w.]+@[\w.]+\.\w+"
print(re.findall(email_pattern, "联系: test@qq.com 或 admin@gmail.com"))
# ===== json - JSON 处理 =====
import json
data = {"name": "张三", "age": 25}
json_str = json.dumps(data, ensure_ascii=False)
print(json_str) # {"name": "张三", "age": 25}
# ===== hashlib - 哈希加密 =====
import hashlib
md5 = hashlib.md5("hello".encode()).hexdigest()
print(md5) # 5d41402abc4b2a76b9719d911017c592
sha256 = hashlib.sha256("hello".encode()).hexdigest()
print(sha256[:32]) # 2cf24dba5fb0a30e26e83b2ac5b
# ===== urllib - URL 操作 =====
from urllib.parse import urlparse, urlencode
url = "https://example.com/path?name=张三&age=25"
parsed = urlparse(url)
print(parsed.scheme) # https
print(parsed.netloc) # example.com
print(parsed.path) # /path
params = {"name": "李四", "age": "30"}
print(urlencode(params)) # name=%E6%9D%8E%E5%9B%9B&age=30
总结
本文从 Python 概述出发,系统介绍了 Python 的核心基础知识:
| 章节 | 核心知识点 |
|---|---|
| Python 概述 | 发展历史、核心特点、应用领域、Python 之禅 |
| 环境搭建 | Python 安装、pip 包管理、虚拟环境、开发工具 |
| 基础语法 | 注释、缩进、变量、数据类型、类型转换、运算符、输入输出 |
| 流程控制 | if-elif-else、match-case、for、while、break/continue/pass、列表推导式 |
| 数据结构 | 列表、元组、字典、集合、各自方法与操作 |
| 函数 | 参数类型、Lambda、高阶函数、装饰器、闭包、递归 |
| 面向对象 | 类与对象、封装、继承、多态、魔术方法 |
| 异常处理 | try-except-finally、raise、自定义异常 |
| 文件操作 | 文件读写、目录操作、JSON、CSV、pathlib |
| 模块与包 | import、自定义模块、包结构、__name__ |
| 常用标准库 | os、sys、datetime、collections、itertools、re 等 |
学习建议:
- 多动手:每个知识点都要亲自写代码运行,理解才能更深刻。
- 由浅入深:先掌握基础语法和数据结构,再学习函数和面向对象。
- 阅读官方文档 :Python 官方文档 是最好的学习资源。
- 项目实践:将所学知识应用到实际项目中,如编写一个简单的学生管理系统、爬虫、数据分析脚本。
- 学习 PEP :阅读 PEP 8 代码风格指南,养成良好的编码习惯。
如果本文对你有帮助,欢迎点赞、收藏、关注!有问题欢迎在评论区交流。