概述
在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关键字 |
| 代码复杂度 | 相对复杂 | 简单直观 |
| 内存效率 | 按需加载 | 按需加载 |
| 状态管理 | 手动维护 | 自动保持 |
重要规则
- 任何包含
yield关键字的函数都是生成器函数 - 生成器函数调用时返回生成器对象,不立即执行函数体
- 需要调用
next()或用于循环才会执行生成器代码 - 生成器在
yield处暂停,保持当前状态