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处暂停,保持当前状态
相关推荐
顾安r1 小时前
11.22 脚本 手机termux项目分析(bash)
前端·python·stm32·flask·bash
IT·小灰灰1 小时前
基于Python的机器学习/数据分析环境搭建完全指南
开发语言·人工智能·python·算法·机器学习·数据分析
程序员爱钓鱼2 小时前
Python职业路线规划:从入门到高级开发者的成长指南
后端·python·trae
程序员爱钓鱼2 小时前
Python 编程实战 · 进阶与职业发展:自动化运维(Ansible、Fabric)
后端·python·trae
rising start2 小时前
二、python面向对象高级
开发语言·python
虎头金猫2 小时前
随时随地处理图片文档!Reubah 加cpolar的实用体验
linux·运维·人工智能·python·docker·开源·visual studio
Yue丶越2 小时前
【Python】基础语法入门(二)
android·开发语言·python
郝学胜-神的一滴3 小时前
Effective Python 第52条:用subprocess模块优雅管理子进程
linux·服务器·开发语言·python
万粉变现经纪人3 小时前
如何解决 pip install 编译报错 ‘cl.exe’ not found(缺少 VS C++ 工具集)问题
开发语言·c++·人工智能·python·pycharm·bug·pip