【测试开发】零基础Python学习笔记(超详细全覆盖)
2026/6/10 14:21:06 网站建设 项目流程

Python完全学习笔记

作者学习笔记,从零基础到协程,一句话击穿本质,覆盖 Python 全栈核心知识。


目录

  • 第 1 章:必备基础知识

  • 第 2 章:初识 Python

  • 第 3 章:Python 核心基础

  • 第 4 章:流程控制语句

  • 第 5 章:函数入门

  • 第 6 章:数据容器

  • 第 7 章:面向对象

  • 第 8 章:函数进阶

  • 第 9 章:错误与异常

  • 第 10 章:模块与包

  • 第 11 章:迭代器 vs 生成器

  • 第 12 章:文件操作

  • 第 13 章:进程与线程

  • 第 14 章:协程

  • 核心概念速查

  • 反直觉提醒


第 1 章:必备基础知识

核心概念

一句话本质:计算机 = 运算器 + 控制器 + 存储器 + 输入设备 + 输出设备。

  • CPU(运算器 + 控制器):只能理解二进制指令

  • 硬盘:持久化存储,容量大但慢(500GB、1TB)

  • 内存:暂时性存储,容量小但快(8GB、16GB)

通俗理解:能安装多少个游戏,取决于硬盘大小;能同时开几个游戏,取决于内存大小。

计算机语言三代演进

代际语言特点1+1 怎么写
第一代机器语言0 和 1,CPU 直接执行10110000 00000001 00000100 00000001
第二代汇编语言助记符,需翻译为机器码mov al, 1/add al, 1
第三代高级语言接近自然语言,需编译/解释print(1 + 1)

编译型 vs 解释型

编译型(C、C++、Go)解释型(Python、JS)
执行方式先编译成 .exe,再运行边解释边运行,不生成 .exe
优点执行效率高跨平台好,开发调试快
缺点跨平台差,编译慢执行效率较低

反直觉提醒:Python 虽然慢,但在 AI 领域是绝对主流。因为 AI 的核心计算发生在 GPU/C++ 库里,Python 只是"指挥官",不是"搬砖工"。


第 2 章:初识 Python

核心概念

一句话本质:Python = 一种优雅、明确、简单的高级解释型语言。

Python 起源

  • 作者:Guido van Rossum(龟叔),荷兰人

  • 时间:1989 年圣诞节开始编写,1991 年发布

  • 命名灵感:喜剧《Monty Python's Flying Circus》

  • 设计哲学:"最好只有一种方法来做一件事"

为什么 AI 领域用 Python?

  1. 简洁直观的开发体验

  2. 丰富强大的框架生态(NumPy、PyTorch、TensorFlow)

  3. 与底层语言高效协作(C/C++ 写核心,Python 调用)

  4. 社区活跃且人才充足

  5. 业内大厂推动

Python 版本

  • Python 2.7(2020 年官方停止维护)

  • Python 3.x(当前主流,推荐 3.10+)

环境搭建

  1. 安装 Python 解释器(python.org,建议 3.13+)

  2. 安装 PyCharm(IDE)

  3. 创建项目,开始编码


第 3 章:Python 核心基础

3.1 字面量

一句话本质:字面量 = 代码中直接写死的值。

'张三' # 字符串字面量 18 # 整数字面量 65.2 # 浮点数字面量

3.2 变量

一句话本质:变量 = 给值起一个名字,方便以后用。

name = '张三' age = 18 weight = 59 weight = 58 # 变量可以重新赋值 ​ print('张三的体重是', weight) # 输出:58

命名规则

  • 只能包含字母、数字、下划线

  • 不能以数字开头

  • 区分大小写(nameName

  • 推荐蛇形命名:user_name(不是userName

3.3 常量

一句话本质:常量 = 不应该被修改的值(Python 没有真正的常量,靠约定)。

ADULT_AGE = 18 # 全大写 + 下划线 = 约定的常量 MAX_USERS = 1200 PASSING_SCORE = 60

3.4 注释

# 单行注释 ​ """ 多行注释 可以写很多行 """

3.5 数据类型

type('张三') # <class 'str'> 字符串 type(18) # <class 'int'> 整数 type(65.2) # <class 'float'> 浮点数 type(True) # <class 'bool'> 布尔值

类型转换

int('18') # 字符串 → 整数:18 str(18) # 整数 → 字符串:'18' float('3.14') # 字符串 → 浮点数:3.14 int(3.99) # 浮点数 → 整数:3(直接截断,不四舍五入)

3.6 字符串

四种定义方式

s1 = '单引号' s2 = "双引号" s3 = '''三单引号 可以换行''' s4 = """三双引号 也可以换行"""

格式化输出

name = '张三' age = 18 ​ # f-string(推荐) print(f'我叫{name},今年{age}岁') ​ # format 方法 print('我叫{},今年{}岁'.format(name, age)) ​ # % 占位符 print('我叫%s,今年%d岁' % (name, age))

精度控制

num = 3.14159 print(f'{num:.2f}') # 保留2位小数:3.14 print(f'{num:10.2f}') # 宽度10,保留2位: 3.14 print(f'{num:010.2f}') # 宽度10,前补0:0000003.14

转义字符

print('换行符:\n') print('制表符:\t') print('反斜杠:\\') print('引号:\'')

3.7 运算符

# 算数运算符 print(10 + 3) # 13 print(10 - 3) # 7 print(10 * 3) # 30 print(10 / 3) # 3.3333... print(10 // 3) # 3(整除) print(10 % 3) # 1(取余) print(10 ** 3) # 1000(幂运算) ​ # 比较运算符 print(10 > 3) # True print(10 == 3) # False print(10 != 3) # True ​ # 逻辑运算符 print(True and False) # False print(True or False) # True print(not True) # False

3.8 输入

name = input('请输入你的名字:') print(f'你好,{name}!') ​ # input 返回的永远是字符串 age = input('请输入你的年龄:') print(type(age)) # <class 'str'> age = int(age) # 需要手动转换

场景代入(电商)

# 电商商品信息 product_name = 'iPhone 15' price = 7999.0 stock = 100 is_on_sale = True ​ print(f'商品:{product_name}') print(f'价格:¥{price:.2f}') print(f'库存:{stock}') print(f'在售:{is_on_sale}')

第 4 章:流程控制语句

核心概念

一句话本质:流程控制 = 让程序学会"判断"和"循环"。

4.1 if 判断

age = 18 ​ if age >= 18: print('成年人') elif age >= 12: print('青少年') else: print('儿童')

三元表达式

status = '成年' if age >= 18 else '未成年'

4.2 while 循环

i = 1 while i <= 5: print(f'第{i}次循环') i += 1

4.3 for 循环

# 遍历字符串 for ch in 'hello': print(ch) ​ # range 生成数字序列 for i in range(5): # 0,1,2,3,4 print(i) ​ for i in range(1, 6): # 1,2,3,4,5 print(i) ​ for i in range(0, 10, 2): # 0,2,4,6,8 print(i)

4.4 break 和 continue

# break:立即结束整个循环 for i in range(10): if i == 5: break print(i) # 0,1,2,3,4 ​ # continue:跳过本次,继续下次循环 for i in range(10): if i % 2 == 0: continue print(i) # 1,3,5,7,9

场景代入(电商)

# 模拟购物车结算 cart = [ {"name": "手机", "price": 2999, "qty": 1}, {"name": "耳机", "price": 199, "qty": 2}, {"name": "充电器", "price": 59, "qty": 0}, ] ​ total = 0 for item in cart: if item["qty"] == 0: continue # 跳过数量为0的商品 subtotal = item["price"] * item["qty"] total += subtotal print(f'{item["name"]} x {item["qty"]} = ¥{subtotal}') ​ print(f'总计:¥{total}')

第 5 章:函数入门

核心概念

一句话本质:函数 = 把一段代码打包,起个名字,需要时"喊名字"就执行。

5.1 定义和调用

# 定义函数 def welcome(): print('欢迎来到电商系统!') ​ # 调用函数 welcome() welcome() # 可以反复调用

5.2 参数

# 位置参数 def greet(name, age): print(f'{name}今年{age}岁') greet('张三', 18) ​ # 关键字参数 greet(age=18, name='张三') ​ # 默认值参数 def greet(name, age=18): print(f'{name}今年{age}岁') greet('张三') # 张三今年18岁 greet('张三', 25) # 张三今年25岁 ​ # 可变参数 *args def calc_sum(*nums): return sum(nums) print(calc_sum(1, 2, 3, 4, 5)) # 15 ​ # 可变关键字参数 **kwargs def print_info(**kwargs): for key, value in kwargs.items(): print(f'{key}: {value}') print_info(name='张三', age=18, city='北京')

5.3 返回值

def add(a, b): return a + b ​ result = add(3, 5) print(result) # 8 ​ # 返回多个值 def get_user(): return '张三', 18 ​ name, age = get_user()

5.4 作用域

# 全局变量 global_var = '我是全局的' ​ def test(): # 局部变量 local_var = '我是局部的' print(global_var) # 可以读取全局变量 print(local_var) ​ # test() 外面访问 local_var 会报错

5.5 递归

def factorial(n): if n == 1: return 1 return n * factorial(n - 1) print(factorial(5)) # 120 (5*4*3*2*1)

反直觉提醒:Python 默认递归深度限制是 1000 层。超过会报RecursionError。可以用sys.setrecursionlimit()修改,但不推荐。

场景代入(电商)

def calculate_discount(price, user_level): """根据用户等级计算折扣""" discounts = {'vip': 0.8, 'svip': 0.7, 'regular': 1.0} rate = discounts.get(user_level, 1.0) return price * rate ​ def checkout(cart_items, user_level): """结算购物车""" total = 0 for item in cart_items: discounted = calculate_discount(item['price'], user_level) subtotal = discounted * item['qty'] total += subtotal return total ​ cart = [ {'name': '手机', 'price': 2999, 'qty': 1}, {'name': '耳机', 'price': 199, 'qty': 2}, ] print(f'VIP 结算价:¥{checkout(cart, "vip"):.2f}')

第 6 章:数据容器

核心概念

一句话本质:数据容器 = 装多个数据的"箱子"。

类型符号特点用途
列表 list[]有序、可变、可重复存储商品列表
元组 tuple()有序、不可变、可重复存储不会改的数据
字典 dict{}键值对、可变存储商品详情
集合 set{}无序、不可重复去重、交并集

6.1 列表 list

# 创建 fruits = ['苹果', '香蕉', '橘子'] ​ # 访问 print(fruits[0]) # 苹果 print(fruits[-1]) # 橘子(倒数第一个) ​ # 切片 print(fruits[0:2]) # ['苹果', '香蕉'] ​ # 添加 fruits.append('葡萄') # 末尾添加 fruits.insert(1, '草莓') # 指定位置添加 ​ # 删除 fruits.remove('香蕉') # 按值删除 del fruits[0] # 按索引删除 fruits.pop(0) # 按索引删除并返回 ​ # 遍历 for fruit in fruits: print(fruit) ​ # 列表推导式 squares = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, ...]

6.2 元组 tuple

# 创建(不可修改) point = (3, 4) print(point[0]) # 3 ​ # 单元素元组要加逗号 single = (1,) # 不是 (1)

6.3 字典 dict

# 创建 user = {'name': '张三', 'age': 18, 'city': '北京'} ​ # 访问 print(user['name']) # 张三 print(user.get('phone', '无')) # 无(不存在返回默认值) ​ # 添加/修改 user['phone'] = '13800138000' user['age'] = 19 ​ # 删除 del user['city'] ​ # 遍历 for key, value in user.items(): print(f'{key}: {value}') ​ # 字典推导式 squares = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}

6.4 集合 set

# 创建(自动去重) nums = {1, 2, 3, 2, 1} print(nums) # {1, 2, 3} # 添加 nums.add(4) # 删除 nums.remove(2) # 集合运算 a = {1, 2, 3} b = {2, 3, 4} print(a & b) # 交集:{2, 3} print(a | b) # 并集:{1, 2, 3, 4} print(a - b) # 差集:{1}

场景代入(电商)

# 商品数据 products = [ {'id': 1, 'name': 'iPhone 15', 'price': 7999, 'tags': ['手机', '苹果']}, {'id': 2, 'name': 'AirPods Pro', 'price': 1899, 'tags': ['耳机', '苹果']}, {'id': 3, 'name': '小米14', 'price': 3999, 'tags': ['手机', '小米']}, ] ​ # 找出所有手机 phones = [p for p in products if '手机' in p['tags']] print(phones) ​ # 所有品牌(去重) brands = {tag for p in products for tag in p['tags']} print(brands) ​ # 价格字典 price_map = {p['name']: p['price'] for p in products} print(price_map) # {'iPhone 15': 7999, ...}

第 7 章:面向对象

核心概念

一句话本质:类 = 模板,对象 = 根据模板造出来的具体东西。

类(模具) → 对象(产品) "手机" 类 → "张三的 iPhone" 对象 "订单" 类 → "订单号 001" 对象

7.1 定义类

class Person: def __init__(self, name, age, gender): self.name = name # 实例属性 self.age = age self.gender = gender def say_hello(self): # 实例方法 print(f'大家好,我叫{self.name},今年{self.age}岁') # 创建对象 p = Person('张三', 18, '男') p.say_hello() # 大家好,我叫张三,今年18岁

7.2 类属性 vs 实例属性

class Dog: species = '犬科' # 类属性(所有对象共享) def __init__(self, name): self.name = name # 实例属性(每个对象独有) dog1 = Dog('旺财') dog2 = Dog('小白') print(dog1.species) # 犬科 print(dog2.species) # 犬科(共享)

7.3 类方法和静态方法

class MyClass: count = 0 def __init__(self): MyClass.count += 1 @classmethod def get_count(cls): # 类方法,操作类属性 return cls.count @staticmethod def utility(): # 静态方法,与类和实例无关 print('我是工具方法')

7.4 继承

class Animal: def __init__(self, name): self.name = name ​ def speak(self): print(f'{self.name}发出声音') ​ class Dog(Animal): def speak(self): # 方法重写 print(f'{self.name}汪汪叫') ​ class Cat(Animal): def speak(self): print(f'{self.name}喵喵叫') ​ dog = Dog('旺财') dog.speak() # 旺财汪汪叫

7.5 多态

# 标准多态 def animal_speak(animal): animal.speak() ​ animal_speak(Dog('旺财')) # 汪汪叫 animal_speak(Cat('咪咪')) # 喵喵叫 ​ # 鸭子多态(不看类型,看行为) class Duck: def speak(self): print('嘎嘎叫') ​ animal_speak(Duck()) # 嘎嘎叫(只要有 speak 方法就行)

7.6 权限控制

class Account: def __init__(self): self.public = '公开的' # 公开 self._protected = '受保护的' # 约定受保护(外部仍可访问) self.__private = '私有的' # 名称改写(外部不易访问)

7.7 魔法方法

class Point: def __init__(self, x, y): self.x = x self.y = y def __str__(self): # print() 时调用 return f'({self.x}, {self.y})' def __eq__(self, other): # == 比较时调用 return self.x == other.x and self.y == other.y def __add__(self, other): # + 运算时调用 return Point(self.x + other.x, self.y + other.y) p1 = Point(1, 2) p2 = Point(3, 4) print(p1) # (1, 2) print(p1 == p2) # False print(p1 + p2) # (4, 6)

场景代入(电商)

class Product: def __init__(self, name, price, stock): self.name = name self.price = price self.stock = stock def __str__(self): return f'{self.name} ¥{self.price} 库存:{self.stock}' class DigitalProduct(Product): def __init__(self, name, price, stock, warranty): super().__init__(name, price, stock) self.warranty = warranty # 保修期 def __str__(self): return super().__str__() + f' 保修:{self.warranty}个月' phone = DigitalProduct('iPhone 15', 7999, 100, 12) print(phone) # iPhone 15 ¥7999 库存:100 保修:12个月

第 8 章:函数进阶

核心概念

一句话本质:函数是一等公民——可以当参数、当返回值、赋给变量。

8.1 函数作为参数

def apply(func, value): return func(value) def double(x): return x * 2 print(apply(double, 5)) # 10

8.2 闭包

一句话本质:闭包 = 内部函数记住了外部函数的变量。

def make_counter(): count = 0 def counter(): nonlocal count count += 1 return count return counter c = make_counter() print(c()) # 1 print(c()) # 2 print(c()) # 3

8.3 装饰器

一句话本质:装饰器 = 不改原函数代码,给它"加功能"。

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) return 'done' result = slow_function() # slow_function 执行耗时 1.0012秒

8.4 lambda

# lambda = 匿名函数(一行搞定) square = lambda x: x ** 2 print(square(5)) # 25 ​ # 常用于排序 users = [('张三', 25), ('李四', 18), ('王五', 30)] users.sort(key=lambda u: u[1]) # 按年龄排序 print(users) # [('李四', 18), ('张三', 25), ('王五', 30)]

场景代入(电商)

# 装饰器:接口计时 def api_timer(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) duration = time.time() - start if duration > 1: print(f'⚠️ 接口 {func.__name__} 响应慢:{duration:.2f}秒') return result return wrapper ​ @api_timer def get_product_list(): time.sleep(0.5) return ['手机', '耳机', '充电器']

第 9 章:错误与异常

核心概念

一句话本质:异常 = 程序运行时的"意外",可以用 try/except 捕获处理。

9.1 捕获异常

try: result = 10 / 0 except ZeroDivisionError: print('不能除以零') except (ValueError, TypeError) as e: print(f'错误:{e}') else: print('没有异常时执行') finally: print('无论如何都执行')

9.2 常见异常

异常原因示例
ValueError值不对int('abc')
TypeError类型不对'1' + 1
KeyError字典键不存在{'a':1}['b']
IndexError列表索引越界[1,2][5]
FileNotFoundError文件不存在open('xxx.txt')
ZeroDivisionError除以零1/0
AttributeError属性不存在None.len()

9.3 自定义异常

class InsufficientStockError(Exception): def __init__(self, product, requested, available): self.product = product self.requested = requested self.available = available super().__init__(f'{product}库存不足:需要{requested},仅有{available}') try: raise InsufficientStockError('iPhone', 10, 3) except InsufficientStockError as e: print(e) # iPhone库存不足:需要10,仅有3

场景代入(电商)

def place_order(product, qty): try: if qty <= 0: raise ValueError('数量必须大于0') if qty > product['stock']: raise InsufficientStockError(product['name'], qty, product['stock']) product['stock'] -= qty return {'status': 'success', 'remaining': product['stock']} except ValueError as e: return {'status': 'error', 'message': str(e)} except InsufficientStockError as e: return {'status': 'error', 'message': str(e)}

第 10 章:模块与包

核心概念

一句话本质:模块 = 一个 .py 文件,包 = 一个文件夹(含__init__.py)。

10.1 导入方式

# 导入整个模块 import math print(math.pi) # 导入指定内容 from math import pi, sqrt print(pi) # 起别名 import numpy as np from math import sqrt as square_root # 导入所有(不推荐) from math import *

10.2 自定义模块

# my_utils.py def add(a, b): return a + b ​ def multiply(a, b): return a * b ​ # main.py from my_utils import add, multiply print(add(3, 5)) # 8

10.3 pip 包管理

pip install requests # 安装 pip install requests==2.28 # 指定版本 pip uninstall requests # 卸载 pip list # 查看已安装 pip freeze > requirements.txt # 导出依赖 pip install -r requirements.txt # 从文件安装

10.4 常用内置模块

import os # 操作系统相关 import sys # 系统相关 import json # JSON 处理 import time # 时间处理 import datetime # 日期时间 import random # 随机数 import math # 数学函数 import re # 正则表达式 import hashlib # 哈希加密

第 11 章:迭代器 vs 生成器

核心概念

一句话本质:迭代器 = 一个一个往外拿数据的对象;生成器 = 按需生成数据,不占内存。

11.1 可迭代对象

# 可迭代对象:能用 for 循环遍历的东西 for i in [1, 2, 3]: # 列表可迭代 print(i) for ch in 'hello': # 字符串可迭代 print(ch)

11.2 迭代器

# 迭代器:有 __next__() 方法的对象 nums = [1, 2, 3] it = iter(nums) # 获取迭代器 print(next(it)) # 1 print(next(it)) # 2 print(next(it)) # 3 # print(next(it)) # StopIteration 异常

11.3 生成器

# 生成器函数(用 yield 替代 return) def countdown(n): while n > 0: yield n n -= 1 for num in countdown(5): print(num) # 5, 4, 3, 2, 1 # 生成器表达式 squares = (x**2 for x in range(10)) # 注意是 () 不是 [] print(next(squares)) # 0 print(next(squares)) # 1

反直觉提醒:生成器只能遍历一次。遍历完就"空了",需要重新创建。

场景代入(电商)

# 大数据量商品分页加载 def load_products_page(page_size=10): """生成器:按页加载商品,不会一次性占用大量内存""" page = 0 while True: # 模拟从数据库分页查询 data = db.query(f'SELECT * FROM products LIMIT {page_size} OFFSET {page * page_size}') if not data: break yield data page += 1 # 使用 for page_data in load_products_page(100): process(page_data) # 每次只处理100条

第 12 章:文件操作

核心概念

一句话本质:文件操作 = 打开 → 读/写 → 关闭。

12.1 文本文件

# 读取 with open('data.txt', 'r', encoding='utf-8') as f: content = f.read() # 读全部 # lines = f.readlines() # 读所有行(列表) # line = f.readline() # 读一行 # 写入 with open('output.txt', 'w', encoding='utf-8') as f: f.write('Hello\n') f.write('World\n') # 追加 with open('output.txt', 'a', encoding='utf-8') as f: f.write('New line\n')

12.2 JSON 文件

import json ​ # 写入 JSON data = {'name': '张三', 'age': 18, 'hobbies': ['编程', '游戏']} with open('user.json', 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) ​ # 读取 JSON with open('user.json', 'r', encoding='utf-8') as f: data = json.load(f) print(data['name']) # 张三

12.3 CSV 文件

import csv ​ # 写入 with open('products.csv', 'w', encoding='utf-8-sig', newline='') as f: writer = csv.writer(f) writer.writerow(['商品名', '价格', '库存']) writer.writerow(['iPhone 15', 7999, 100]) writer.writerow(['AirPods Pro', 1899, 500]) ​ # 读取 with open('products.csv', 'r', encoding='utf-8-sig') as f: reader = csv.reader(f) for row in reader: print(row)

场景代入(电商)

import json ​ # 导出订单为 JSON orders = [ {'order_id': 'ORD001', 'user': '张三', 'amount': 2999, 'status': '已支付'}, {'order_id': 'ORD002', 'user': '李四', 'amount': 1899, 'status': '待支付'}, ] ​ with open('orders_export.json', 'w', encoding='utf-8') as f: json.dump(orders, f, ensure_ascii=False, indent=2)

第 13 章:进程与线程

核心概念

一句话本质:进程 = 一个程序(独立内存),线程 = 程序里的一条执行路径(共享内存)。

进程(公司) 线程(员工) ├── 线程1(开发部) → 共享公司资源(内存) ├── 线程2(测试部) └── 线程3(运维部)

13.1 多线程

import threading import time ​ def task(name, duration): print(f'{name}开始') time.sleep(duration) print(f'{name}结束(耗时{duration}秒)') ​ # 创建线程 t1 = threading.Thread(target=task, args=('任务A', 2)) t2 = threading.Thread(target=task, args=('任务B', 3)) ​ # 启动 t1.start() t2.start() ​ # 等待完成 t1.join() t2.join() print('所有任务完成')

13.2 多进程

from multiprocessing import Process import time def cpu_task(n): total = sum(i * i for i in range(n)) print(f'计算结果:{total}') if __name__ == '__main__': p1 = Process(target=cpu_task, args=(1000000,)) p2 = Process(target=cpu_task, args=(2000000,)) p1.start() p2.start() p1.join() p2.join()

13.3 线程 vs 进程

线程进程
内存共享独立
创建开销
适合场景IO 密集(网络、文件)CPU 密集(计算)
GIL 限制受 GIL 限制,不能真正并行不受 GIL 限制

反直觉提醒:Python 的多线程受 GIL(全局解释器锁)限制,同一时刻只能有一个线程执行 Python 字节码。所以多线程不能加速 CPU 密集型任务,只能加速 IO 密集型任务(等网络、等文件读写时,其他线程可以运行)。

13.4 线程同步

import threading ​ lock = threading.Lock() counter = 0 ​ def increment(): global counter for _ in range(100000): with lock: # 加锁,防止竞争 counter += 1 ​ threads = [threading.Thread(target=increment) for _ in range(5)] for t in threads: t.start() for t in threads: t.join() ​ print(counter) # 500000(正确)

第 14 章:协程

核心概念

一句话本质:协程 = 比线程更轻量的"并发"方式,用async/await语法,单线程实现高并发。

线程:操作系统调度(开销大) 协程:程序自己调度(开销极小)

14.1 基本语法

import asyncio ​ async def fetch_data(url, delay): print(f'开始请求 {url}') await asyncio.sleep(delay) # 模拟网络请求 print(f'请求完成 {url}') return f'{url} 的数据' ​ async def main(): # 并发执行 results = await asyncio.gather( fetch_data('http://api1.com', 2), fetch_data('http://api2.com', 3), fetch_data('http://api3.com', 1), ) print(results) ​ asyncio.run(main()) # 总耗时约 3 秒(最长的那个),而不是 6 秒

14.2 协程 vs 线程 vs 进程

协程线程进程
调度程序自己操作系统操作系统
开销极小中等
并发单线程高并发多线程并发多进程并行
适合场景大量 IO 操作一般 IO 操作CPU 密集
复杂度中等需要锁需要 IPC

场景代入(电商)

import asyncio import aiohttp ​ async def check_stock(session, product_id): async with session.get(f'http://api.com/stock/{product_id}') as resp: data = await resp.json() return product_id, data['stock'] ​ async def batch_check_stock(product_ids): async with aiohttp.ClientSession() as session: tasks = [check_stock(session, pid) for pid in product_ids] results = await asyncio.gather(*tasks) return dict(results) ​ # 同时检查 100 个商品的库存,而不是一个一个查 stock = asyncio.run(batch_check_stock(range(1, 101)))

核心概念速查

概念一句话本质
变量给值起名字
函数把代码打包,起名字
对象的模板
对象类的具体实例
列表有序可变的箱子
元组有序不可变的箱子
字典键值对的箱子
集合无序不重复的箱子
迭代器一个一个往外拿
生成器按需生产,不占库存
装饰器不改代码,加功能
闭包内部函数记住外部变量
异常程序的"意外"
模块一个 .py 文件
__init__.py的文件夹
进程独立的程序(独立内存)
线程程序里的一条路(共享内存)
协程比线程更轻量的并发

反直觉提醒

1. Python 没有真正的常量

MAX_USERS = 100 # 约定的常量 MAX_USERS = 200 # 语法上完全合法,Python 不会阻止你

Python 靠"全大写命名"约定表示常量,但语言本身不限制修改。

2. 整数除法会截断而不是四舍五入

int(3.99) # 3,不是 4 int(-3.99) # -3,不是 -4(向零截断)

要四舍五入:round(3.99)→ 4

3. 列表是引用类型

a = [1, 2, 3] b = a # b 和 a 指向同一个列表 b.append(4) print(a) # [1, 2, 3, 4] ← a 也变了! ​ # 要复制: b = a.copy() # 或 b = a[:]

4. 默认参数的陷阱

# ❌ 危险:默认参数在函数定义时只计算一次 def add_item(item, lst=[]): lst.append(item) return lst ​ print(add_item('a')) # ['a'] print(add_item('b')) # ['a', 'b'] ← 不是 ['b']! ​ # ✅ 正确做法 def add_item(item, lst=None): if lst is None: lst = [] lst.append(item) return lst

5. 字符串是不可变的

s = 'hello' # s[0] = 'H' # ❌ TypeError s = 'Hello' # ✅ 这是创建了新字符串,不是修改原字符串

6. 多线程受 GIL 限制

Python 的多线程不能真正并行执行 CPU 密集型任务。要加速计算,用多进程(multiprocessing)或协程(asyncio)。

7. 生成器只能遍历一次

g = (x**2 for x in range(5)) list(g) # [0, 1, 4, 9, 16] list(g) # [] ← 空了!需要重新创建

8.is==不一样

a = [1, 2, 3] b = [1, 2, 3] a == b # True(值相等) a is b # False(不是同一个对象) ​ # 小整数缓存(-5 到 256) x = 256 y = 256 x is y # True(Python 缓存了小整数) ​ x = 257 y = 257 x is y # False(超出了缓存范围)

最后更新:2026年6月

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询