上一篇我们掌握了 Python 入门基础,这一篇将聚焦核心进阶内容 ------ 数据结构、函数、模块、文件操作和面向对象编程。这些是写出高效、可维护代码的关键,同样搭配了详细表格和可运行的代码示例,跟着练就能吃透!
一、核心数据结构:高效组织数据的 "容器"
数据结构是存储和处理数据的方式。Python 内置了多种实用结构,掌握它们能大幅提升代码效率。
1.1 序列类型:列表(List)与元组(Tuple)
| 类型 | 特点 | 核心操作 | 应用场景 |
|---|---|---|---|
| 列表 | 可变(可增删改)、有序 | 增(append/insert)、删(pop/remove)、改(索引赋值)、查(索引 / 切片) |
需动态修改的数据(如待办清单) |
| 元组 | 不可变(创建后不能改)、有序 | 查(索引 / 切片)、拆包 | 固定数据(如坐标 (x,y)、配置项) |
💡 解释:
- 列表 适合需要频繁修改的场景;
- 元组 更安全、内存更小,适合用作字典的键或函数返回多个值。
列表(List)代码示例:
# 1. 定义列表
fruits = ["apple", "banana", "cherry"]
# 2. 增:添加元素
fruits.append("date") # 末尾添加
print(fruits) # 输出:['apple', 'banana', 'cherry', 'date']
fruits.insert(1, "orange") # 指定位置插入
print(fruits) # 输出:['apple', 'orange', 'banana', 'cherry', 'date']
# 3. 删:移除元素
fruits.pop(2) # 按索引删除(默认删最后一个)
print(fruits) # 输出:['apple', 'orange', 'cherry', 'date']
fruits.remove("orange") # 按值删除
print(fruits) # 输出:['apple', 'cherry', 'date']
# 4. 改:修改元素
fruits[0] = "grape"
print(fruits) # 输出:['grape', 'cherry', 'date']
# 5. 切片:获取子列表(左闭右开)
print(fruits[1:3]) # 输出:['cherry', 'date'](索引1到2)
print(fruits[:2]) # 输出:['grape', 'cherry'](从开头到索引1)
print(fruits[::2]) # 输出:['grape', 'date'](步长2,间隔取元素)
元组(Tuple)代码示例:
# 1. 定义元组(小括号可省略,但建议加上)
point = (3, 4)
color = "red", "green", "blue" # 省略括号的写法
# 2. 查:通过索引或切片(同列表)
print(point[0]) # 输出:3
print(color[1:]) # 输出:('green', 'blue')
# 3. 不可变特性(尝试修改会报错)
try:
point[0] = 5
except TypeError as e:
print(e) # 输出:'tuple' object does not support item assignment
# 4. 拆包:快速提取元素
x, y = point # 元组长度需与变量数一致
print(x, y) # 输出:3 4
# 5. 单元素元组(必须加逗号,否则会被识别为其他类型)
single = (5,) # 正确定义
print(type(single)) # 输出:<class 'tuple'>
1.2 映射与集合:字典(Dict)与集合(Set)
| 类型 | 特点 | 核心操作 | 应用场景 |
|---|---|---|---|
| 字典 | 键值对存储、无序(Python 3.7+ 保持插入顺序) | 增(键赋值)、删(del/pop)、查(键索引 / .get())、字典推导式 |
存储关联数据(如用户信息) |
| 集合 | 无序、唯一元素 | 去重、交集(&)、并集(` |
)、差集(-`) |
💡 解释:
- 字典 是 Python 最常用的数据结构之一,查找效率高(O(1));
- 集合 利用哈希表实现,天然去重,集合运算非常高效。
字典(Dict)代码示例:
# 1. 定义字典
user = {
"name": "Alice",
"age": 25,
"is_student": False
}
# 2. 查:通过键获取值(推荐用 get,避免键不存在报错)
print(user["name"]) # 输出:Alice
print(user.get("age")) # 输出:25
print(user.get("gender", "unknown")) # 键不存在时返回默认值:unknown
# 3. 增/改:键存在则改,不存在则增
user["age"] = 26 # 修改
user["gender"] = "female" # 新增
print(user) # 输出:{'name': 'Alice', 'age': 26, 'is_student': False, 'gender': 'female'}
# 4. 删:删除键值对
del user["is_student"]
print(user) # 输出:{'name': 'Alice', 'age': 26, 'gender': 'female'}
# 5. 字典推导式:快速生成字典
numbers = [1, 2, 3]
square = {num: num**2 for num in numbers}
print(square) # 输出:{1: 1, 2: 4, 3: 9}
集合(Set)代码示例:
# 1. 定义集合(去重特性)
nums = {1, 2, 2, 3, 4, 4}
print(nums) # 输出:{1, 2, 3, 4}(自动去重)
# 2. 转集合去重(列表→集合→列表)
duplicates = [5, 5, 6, 7, 7]
unique = list(set(duplicates))
print(unique) # 输出:[5, 6, 7](顺序可能变化,因为集合无序)
# 3. 集合运算
a = {1, 2, 3}
b = {3, 4, 5}
print(a & b) # 交集:{3}(两集合都有的元素)
print(a | b) # 并集:{1, 2, 3, 4, 5}(所有元素)
print(a - b) # 差集:{1, 2}(a有b没有的元素)
1.3 深浅拷贝:避免 "意外修改" 的坑
| 操作 | 特点 | 适用场景 |
|---|---|---|
| 赋值 | 共享内存地址,修改一个会影响另一个 | 无需独立副本时 |
| 浅拷贝 | 拷贝外层容器,内层对象仍共享(如列表中的列表) | 容器内元素为不可变类型(int/str 等) |
| 深拷贝 | 完全独立拷贝,内外层都不共享 | 容器内有可变子对象(如嵌套列表) |
💡 解释:
- 浅拷贝 用
copy.copy()或list[:];- 深拷贝 用
copy.deepcopy(),适用于复杂嵌套结构。
代码示例:
import copy
# 原始数据(嵌套列表,内层是可变对象)
original = [1, [2, 3]]
# 1. 赋值:共享内存
assigned = original
assigned[0] = 100
assigned[1][0] = 200
print(original) # 输出:[100, [200, 3]](原始数据被修改)
# 2. 浅拷贝(copy.copy 或列表切片[:])
original = [1, [2, 3]] # 重置原始数据
shallow_copied = copy.copy(original) # 等价于 original[:]
shallow_copied[0] = 100 # 修改外层元素(不可变类型)
shallow_copied[1][0] = 200 # 修改内层元素(可变类型)
print(original) # 输出:[1, [200, 3]](内层被修改,外层未改)
# 3. 深拷贝(copy.deepcopy)
original = [1, [2, 3]] # 重置原始数据
deep_copied = copy.deepcopy(original)
deep_copied[0] = 100
deep_copied[1][0] = 200
print(original) # 输出:[1, [2, 3]](原始数据完全不受影响)
二、函数深入学习:模块化代码的核心
函数是封装代码的基本单位,掌握函数的高级用法能让代码更简洁、复用性更强。
2.1 函数基础与参数机制
| 函数要素 | 说明 |
|---|---|
| 定义与调用 | 用 def 定义,函数名后加 () 调用 |
| 返回值 | 用 return 返回结果,无 return 则返回 None |
| 位置参数 | 按顺序传递的参数,必须传且个数匹配 |
| 关键字参数 | 用 key=value 形式传递,可打乱顺序,常用于指定默认值参数 |
| 可变参数 | *args 接收任意个位置参数(元组),**kwargs 接收任意个关键字参数(字典) |
代码示例:
# 1. 基础函数:定义与返回值
def add(a, b): # a和b是位置参数
return a + b # 返回计算结果
result = add(3, 5)
print(result) # 输出:8
# 2. 关键字参数与默认值
def greet(name, greeting="Hello"): # greeting有默认值,是关键字参数
return f"{greeting}, {name}!"
print(greet("Alice")) # 输出:Hello, Alice!(用默认greeting)
print(greet("Bob", greeting="Hi")) # 输出:Hi, Bob!(指定关键字参数)
# 3. 可变参数:*args(接收位置参数)
def sum_numbers(*args): # args是元组,接收任意个参数
return sum(args)
print(sum_numbers(1, 2, 3)) # 输出:6
print(sum_numbers(10, 20, 30, 40)) # 输出:100
# 4. 可变参数:**kwargs(接收关键字参数)
def print_info(**kwargs): # kwargs是字典
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25)
# 输出:
# name: Alice
# age: 25
2.2 作用域与关键字
Python 变量作用域遵循 LEGB 原则 :
L ocal(局部) → E nclosing(嵌套) → G lobal(全局) → Built-in(内置)
| 关键字 | 作用 |
|---|---|
global |
在局部作用域中声明全局变量 |
nonlocal |
在嵌套函数中声明外层(非全局)变量 |
代码示例:
# 全局变量
global_var = "全局变量"
def outer():
# 嵌套作用域变量
outer_var = "外层变量"
def inner():
# 局部变量
local_var = "局部变量"
print(local_var) # 访问局部变量
# 用nonlocal访问外层变量
nonlocal outer_var
outer_var = "修改后的外层变量"
# 用global访问全局变量
global global_var
global_var = "修改后的全局变量"
inner()
print(outer_var) # 输出:修改后的外层变量(被inner修改)
outer()
print(global_var) # 输出:修改后的全局变量(被inner修改)
2.3 高级函数:闭包、装饰器、生成器
| 高级函数 | 特点 | 应用场景 |
|---|---|---|
| 闭包 | 内层函数引用外层变量,且外层函数返回内层函数 | 封装私有变量、实现装饰器基础 |
| 装饰器 | 不修改原函数代码,为函数添加额外功能 | 日志记录、权限校验 |
| 生成器 | 用 yield 返回值,按需生成(节省内存) |
处理大数据流、无限序列 |
闭包代码示例:
def make_counter():
count = 0 # 外层变量,被内层函数引用
def counter():
nonlocal count # 声明为非局部变量
count += 1
return count
return counter # 返回内层函数
# 创建两个计数器(各自独立维护count)
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # 输出:1
print(counter1()) # 输出:2
print(counter2()) # 输出:1(与counter1不干扰)
装饰器代码示例:
# 定义装饰器:记录函数执行时间
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:.2f}秒")
return result # 返回原函数结果
return wrapper
# 用@语法给函数加装饰器
@timer
def slow_function(seconds):
time.sleep(seconds) # 模拟耗时操作
slow_function(1) # 输出:slow_function执行时间:1.00秒
生成器代码示例:
# 生成器函数:用yield返回值
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a # 每次调用返回一个值,暂停执行
a, b = b, a + b
# 生成前5个斐波那契数
for num in fibonacci(5):
print(num) # 输出:0 1 1 2 3
# 生成器表达式(类似列表推导式,用())
gen = (x**2 for x in range(5))
print(list(gen)) # 输出:[0, 1, 4, 9, 16]
三、模块与包:代码组织与复用
模块(.py 文件)和包(模块目录)是 Python 组织大型项目的核心。
3.1 模块导入方式
| 导入方式 | 语法示例 | 说明 |
|---|---|---|
| 导入整个模块 | import module |
使用时需加模块名前缀(如 module.func()) |
| 导入模块中的指定成员 | from module import func, var |
可直接使用成员(如 func()) |
| 导入模块并取别名 | import module as alias |
简化模块名(如 import numpy as np) |
| 导入模块中所有成员 | from module import * |
不推荐,可能导致命名冲突 |
💡 建议 :优先使用
import module或from module import specific,避免import *。
代码示例(假设存在 mymodule.py):
# mymodule.py 内容
def add(a, b):
return a + b
PI = 3.14
# 导入示例
import mymodule
print(mymodule.add(2, 3)) # 输出:5
print(mymodule.PI) # 输出:3.14
from mymodule import add, PI
print(add(2, 3)) # 输出:5
print(PI) # 输出:3.14
import mymodule as mm
print(mm.add(2, 3)) # 输出:5
3.2 常用标准库
Python 自带的标准库能解决很多常见问题,无需重复造轮子:
| 库名 | 功能 | 核心用法示例 |
|---|---|---|
time / datetime |
时间处理 | time.sleep(1)、datetime.now() |
random |
生成随机数 | random.randint(1, 10)、random.choice([...]) |
os |
系统操作(文件 / 目录) | os.listdir()、os.mkdir() |
sys |
与解释器交互 | sys.argv、sys.exit() |
代码示例:
import time
import datetime
import random
import os
# 时间处理
print(datetime.datetime.now()) # 输出:当前时间(如2023-10-01 12:00:00)
time.sleep(1) # 程序暂停1秒
# 随机数
print(random.randint(1, 10)) # 输出:1-10之间的随机整数
print(random.choice(["a", "b", "c"])) # 输出:随机选择一个元素
# 系统操作
print(os.listdir(".")) # 输出:当前目录下的文件列表
os.makedirs("test_dir", exist_ok=True) # 创建目录(已存在不报错)
3.3 包的创建与使用
包是包含多个模块的目录,需包含 __init__.py 文件(可为空):
mypackage/ # 包目录
├── __init__.py # 包标识文件(可空,也可写初始化代码)
├── module1.py # 模块1
└── module2.py # 模块2
代码示例:
# mypackage/module1.py
def func1():
return "来自module1的func1"
# mypackage/__init__.py(可选)
from . import module1 # 允许直接通过包访问module1
# 外部使用包
from mypackage import module1
print(module1.func1()) # 输出:来自module1的func1
from mypackage.module2 import func2 # 假设module2有func2
四、文件操作与异常处理:robustness 保障
4.1 文件读写模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
r |
只读(默认),文件不存在则报错 | 读取文本文件 |
w |
只写,文件不存在则创建,存在则覆盖 | 新建 / 覆盖文件 |
a |
追加,文件不存在则创建,内容加在末尾 | 日志记录(不覆盖历史) |
r+ |
读写,文件不存在则报错 | 读取并修改文件 |
b |
二进制模式(如 rb、wb) |
处理图片、视频等二进制文件 |
💡 最佳实践 :始终使用
with open(...) as f:,自动管理文件关闭。
文本文件读写示例:
# 1. 写入文件(w模式)
with open("test.txt", "w", encoding="utf-8") as f:
f.write("Hello, Python!\n")
f.writelines(["第一行\n", "第二行\n"])
# 2. 读取文件(r模式)
with open("test.txt", "r", encoding="utf-8") as f:
print(f.read()) # 读取全部内容
f.seek(0) # 回到文件开头
print(f.readline()) # 读取一行
print(f.readlines()) # 读取剩余行
# 3. 追加内容(a模式)
with open("test.txt", "a", encoding="utf-8") as f:
f.write("追加的内容\n")
二进制文件读写示例(如图片):
# 复制图片(二进制模式)
with open("source.jpg", "rb") as src, open("copy.jpg", "wb") as dst:
dst.write(src.read())
4.2 异常处理
异常处理能捕获程序错误,避免崩溃,核心语法:try-except-else-finally。
| 异常类型 | 说明 |
|---|---|
IndentationError |
缩进错误(Python 对缩进敏感) |
KeyError |
字典中访问不存在的键 |
IndexError |
列表索引越界 |
ValueError |
数据类型正确但值不合适(如 int("a")) |
TypeError |
数据类型错误(如 1 + "a") |
代码示例:
# 基础异常处理
try:
num = int(input("请输入数字:"))
result = 10 / num
except ValueError:
print("输入不是有效数字!")
except ZeroDivisionError:
print("不能除以0!")
else:
print(f"结果是:{result}")
finally:
print("操作结束")
# 自定义异常
class TooBigError(Exception):
pass
def check_number(n):
if n > 100:
raise TooBigError("数字不能超过100")
try:
check_number(200)
except TooBigError as e:
print(e) # 输出:数字不能超过100
五、面向对象编程(OOP):抽象与封装的艺术
面向对象是大型项目的主流编程范式,核心是 "类(模板)" 和 "对象(实例)"。
5.1 类与对象基础
| 概念 | 说明 |
|---|---|
| 类 | 用 class 定义的模板,包含属性和方法 |
| 对象 | 类的实例(如 person = Person()) |
| 属性 | 类 / 对象的数据(如 name、age) |
| 方法 | 类 / 对象的函数(如 eat()、sleep()) |
代码示例:
# 定义类
class Person:
species = "人类" # 类属性(所有实例共享)
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
def greet(self):
return f"你好,我是{self.name},今年{self.age}岁"
# 创建对象
person1 = Person("Alice", 25)
print(person1.greet()) # 输出:你好,我是Alice,今年25岁
print(Person.species) # 输出:人类
5.2 三大特性:封装、继承、多态
| 特性 | 说明 |
|---|---|
| 封装 | 隐藏内部实现,通过方法暴露接口 |
| 继承 | 子类继承父类的属性和方法,可扩展 |
| 多态 | 不同对象调用同一方法,表现出不同行为 |
继承与多态示例:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现speak方法")
class Dog(Animal):
def speak(self):
return f"{self.name}汪汪叫"
class Cat(Animal):
def speak(self):
return f"{self.name}喵喵叫"
def make_speak(animal):
print(animal.speak())
dog = Dog("旺财")
cat = Cat("咪宝")
make_speak(dog) # 输出:旺财汪汪叫
make_speak(cat) # 输出:咪宝喵喵叫
5.3 高级特性:魔法方法与单例模式
| 高级特性 | 说明 |
|---|---|
| 魔法方法 | 双下划线开头的方法(如 __init__、__str__),自动触发 |
| 单例模式 | 确保类只有一个实例(如配置管理器) |
魔法方法示例:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"{self.title}(作者:{self.author})"
def __len__(self):
return len(self.title)
book = Book("Python编程", "张三")
print(book) # 调用 __str__
print(len(book)) # 调用 __len__,输出:6
单例模式示例:
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # 输出:True
总结:进阶之路,实践为要
这部分内容是 Python 编程的 "中流砥柱":
- 数据结构 决定了数据的组织效率;
- 函数和模块 提升了代码复用性;
- 异常处理 保障了程序稳健性;
- 面向对象 为大型项目提供了清晰的架构。