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处暂停,保持当前状态
相关推荐
花酒锄作田10 小时前
使用 pkgutil 实现动态插件系统
python
前端付豪14 小时前
LangChain链 写一篇完美推文?用SequencialChain链接不同的组件
人工智能·python·langchain
曲幽14 小时前
FastAPI实战:打造本地文生图接口,ollama+diffusers让AI绘画更听话
python·fastapi·web·cors·diffusers·lcm·ollama·dreamshaper8·txt2img
老赵全栈实战15 小时前
Pydantic配置管理最佳实践(一)
python
阿尔的代码屋21 小时前
[大模型实战 07] 基于 LlamaIndex ReAct 框架手搓全自动博客监控 Agent
人工智能·python
AI探索者2 天前
LangGraph StateGraph 实战:状态机聊天机器人构建指南
python
AI探索者2 天前
LangGraph 入门:构建带记忆功能的天气查询 Agent
python
FishCoderh2 天前
Python自动化办公实战:批量重命名文件,告别手动操作
python
躺平大鹅2 天前
Python函数入门详解(定义+调用+参数)
python
曲幽2 天前
我用FastAPI接ollama大模型,差点被asyncio整崩溃(附对话窗口实战)
python·fastapi·web·async·httpx·asyncio·ollama