Python SQLite多线程、上下文管理器与生成器全面解析

概述

在Python开发中,有一些核心概念

  • SQLite数据库操作
  • 上下文管理器(非大模型的上下文,这里指的是链接关闭数据库)
  • 迭代器和生成器

本文通过实际代码示例,详细讲解这些技术的原理和应用。

1. SQLite多线程支持

检查SQLite线程安全模式

python 复制代码
import sqlite3

# 方法1:检查编译选项
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
cursor.execute('PRAGMA compile_options;')
options = [row[0] for row in cursor.fetchall()]
thread_options = [opt for opt in options if 'THREAD' in opt.upper()]
print("线程安全选项:", thread_options)

# 方法2:实际多线程测试
import threading

def test_thread_safety():
    results = {}
    
    def worker(thread_id, db_path, results):
        try:
            conn = sqlite3.connect(db_path, check_same_thread=False)
            cursor = conn.cursor()
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS test (id INTEGER, data TEXT)
            ''')
            cursor.execute(
                "INSERT INTO test VALUES (?, ?)", 
                (thread_id, f"Data from {thread_id}")
            )
            conn.commit()
            conn.close()
            results[thread_id] = "成功"
        except Exception as e:
            results[thread_id] = f"失败: {e}"

    threads = []
    for i in range(3):
        thread = threading.Thread(target=worker, args=(i, ':memory:', results))
        threads.append(thread)
        thread.start()
    
    for thread in threads:
        thread.join()
    
    return all("成功" in result for result in results.values())

print("多线程支持:", test_thread_safety())

SQLite多线程最佳实践(WML模式)

python 复制代码
import sqlite3
import threading

class ThreadSafeDatabase:
    def __init__(self, db_path):
        self.db_path = db_path
        self.local = threading.local()
    
    def get_connection(self):
        """每个线程独立的数据库连接"""
        if not hasattr(self.local, 'conn'):
            self.local.conn = sqlite3.connect(
                self.db_path, 
                check_same_thread=False
            )
            # 启用WAL模式提升并发性能
            self.local.conn.execute("PRAGMA journal_mode=WAL;")
        return self.local.conn

# 使用示例
db_manager = ThreadSafeDatabase('test.db')

def worker_thread(thread_id):
    conn = db_manager.get_connection()
    cursor = conn.cursor()
    cursor.execute("INSERT INTO data VALUES (?, ?)", (thread_id, f"Message"))
    conn.commit()
    print(f"线程{thread_id}操作完成")

2. 上下文管理器与@contextmanager

基础上下文管理器

python 复制代码
# 传统文件操作
file = open('test.txt', 'w')
try:
    file.write('Hello')
finally:
    file.close()  # 必须手动关闭

# 使用with语句
with open('test.txt', 'w') as file:
    file.write('Hello')
# 文件自动关闭

自定义上下文管理器类

python 复制代码
class Timer:
    def __enter__(self):
        import time
        self.start = time.time()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        print(f"耗时: {self.end - self.start:.2f}秒")

with Timer():
    import time
    time.sleep(1)
    print("操作完成")

使用@contextmanager简化

python 复制代码
from contextlib import contextmanager
import time

@contextmanager
def timer(description="操作"):
    start = time.time()
    try:
        yield  # 暂停点,执行with块内的代码
    finally:
        end = time.time()
        print(f"{description}耗时: {end - start:.2f}秒")

with timer("数据库查询"):
    time.sleep(0.5)
    print("查询完成")

数据库事务上下文管理器

python 复制代码
from contextlib import contextmanager
import sqlite3

@contextmanager
def database_transaction(db_path):
    """自动管理数据库事务的上下文管理器"""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    try:
        yield cursor  # 将cursor交给with块使用
        conn.commit()  # 没有异常时提交
        print("✅ 事务提交成功")
    except Exception as e:
        conn.rollback()  # 有异常时回滚
        print(f"❌ 事务回滚: {e}")
        raise e
    finally:
        conn.close()  # 总是关闭连接

# 使用示例
with database_transaction(':memory:') as cursor:
    cursor.execute("CREATE TABLE users (id INTEGER, name TEXT)")
    cursor.execute("INSERT INTO users VALUES (1, 'Alice')")

3. 迭代器详解

基础迭代器使用

inter()的用法:每次返回一个对象,节省内存

python 复制代码
# 列表是可迭代对象
my_list = [1, 2, 3]

# 手动使用迭代器
iterator = iter(my_list)
print(next(iterator))  # 1
print(next(iterator))  # 2
print(next(iterator))  # 3

# for循环背后就是迭代器
for item in my_list:
    print(item)

自定义迭代器类

python 复制代码
class Counter:
    def __init__(self, start, end):
        self.current = start
        self.end = end
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current <= self.end:
            result = self.current
            self.current += 1
            return result
        raise StopIteration()

# 使用自定义迭代器
counter = Counter(1, 3)
for num in counter:
    print(num)  # 1, 2, 3

4. 生成器深度解析

只要有yield 就是生成器

生成器函数基础

python 复制代码
def simple_generator():
    yield 1
    yield 2
    yield 3

# 生成器函数返回生成器对象
gen = simple_generator()
print(gen)  # <generator object simple_generator at 0x...>

print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3

生成器 vs 普通函数

python 复制代码
def normal_function():
    result = []
    for i in range(1000000):
        result.append(i)
    return result  # 一次性返回所有数据,占用大量内存

def generator_function():
    for i in range(1000000):
        yield i  # 每次只生成一个数据,节省内存

# 内存占用对比
import sys
print(f"列表内存: {sys.getsizeof(normal_function())} 字节")
print(f"生成器内存: {sys.getsizeof(generator_function())} 字节")

生成器表达式

python 复制代码
# 列表推导式 - 立即创建完整列表
squares_list = [x*x for x in range(5)]
print(squares_list)  # [0, 1, 4, 9, 16]

# 生成器表达式 - 按需生成
squares_gen = (x*x for x in range(5))
print(squares_gen)  # <generator object <genexpr> at 0x...>
print(list(squares_gen))  # [0, 1, 4, 9, 16]

实用生成器案例

python 复制代码
# 读取大文件
def read_large_file(filename):
    with open(filename, 'r') as f:
        for line in f:
            yield line.strip()  # 每次只读一行到内存

# 斐波那契数列生成器
def fibonacci(limit):
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

for i, fib in enumerate(fibonacci(10)):
    print(f"F({i}) = {fib}")

生成器状态保持

python 复制代码
def interactive_generator():
    total = 0
    while True:
        value = yield total  # 可以接收外部发送的值
        if value is not None:
            total += value
        else:
            total += 1

gen = interactive_generator()
next(gen)  # 启动生成器,返回0
print(gen.send(10))  # 发送10,返回10
print(next(gen))     # 加1,返回11
print(gen.send(5))   # 发送5,返回16

5. 关键知识点总结

SQLite多线程要点

  • 每个线程使用独立的数据库连接
  • 启用WAL模式提升并发性能
  • 使用连接池管理数据库连接
  • 设置适当的超时时间处理锁竞争

上下文管理器核心概念

  • with语句自动管理资源生命周期
  • @contextmanager装饰器简化上下文管理器创建
  • SETUP代码在yield之前执行
  • CLEANUP代码在yield之后执行
  • 使用try-finally确保清理代码总是执行

迭代器与生成器区别

特性 迭代器 生成器
创建方式 实现__iter____next__ 使用yield关键字
代码复杂度 相对复杂 简单直观
内存效率 按需加载 按需加载
状态管理 手动维护 自动保持

重要规则

  1. 任何包含yield关键字的函数都是生成器函数
  2. 生成器函数调用时返回生成器对象,不立即执行函数体
  3. 需要调用next()或用于循环才会执行生成器代码
  4. 生成器在yield处暂停,保持当前状态
相关推荐
心中有国也有家2 小时前
GE图引擎深度解析——CANN的计算图优化与执行引擎
人工智能·pytorch·python·学习·numpy
卷毛的技术笔记3 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥3 小时前
匿名函数 lambda + 高阶函数
java·python·算法
vb2008113 小时前
FastAPI APIRouter
开发语言·python
adrninistrat0r3 小时前
Java调用链MCP分析工具
java·python·ai编程
杨充4 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
meilindehuzi_a4 小时前
深入浅出数据结构:Python 字典(Dict)与集合(Set)的哈希表底层全链路追踪
数据结构·python·散列表
Lucas凉皮5 小时前
20243408 2025-2026-2 《Python程序设计》综合实践报告
python·实验报告
键盘上的猫头鹰5 小时前
【MySQL 教程(八)】索引、事务、用户管理、导入导出与分页查询
数据库·python·mysql
薛定谔的猫-菜鸟程序员5 小时前
2小时智能体开发一个智能体?我用CodeArts Agent 和 AtomCode 开发了一个适老化智能体。
人工智能·python·agent