如何修补sqlite3.Cursor使其接受并忽略任意关键字参数?
问题根源
- 替换Cursor类无效的核心原因:你只替换了
sqlite3.Cursor类,但conn.cursor()方法本身的签名不支持额外关键字参数。调用conn.cursor(row_factory='foo')时,参数会先被Connection.cursor方法校验——它的原生定义里没有**kwargs,所以直接抛出TypeError,根本没机会走到自定义Cursor的__init__方法。 - conn.cursor属性只读的原因:
sqlite3.Connection是C扩展实现的类,它的cursor属性是内置的只读方法绑定,无法直接赋值修改。
解决方案
要解决这个问题,需要修补sqlite3.Connection.cursor方法,让它忽略多余的关键字参数,同时返回你的自定义Cursor实例。
步骤1:定义自定义Cursor类
import sqlite3 from unittest.mock import patch class TestCursor(sqlite3.Cursor): def __init__(self, *args, **kwargs): # 忽略所有额外关键字参数,仅传递必要参数给父类构造 super().__init__(*args)
步骤2:修补Connection.cursor方法
写一个包装函数,接收任意关键字参数并忽略,然后返回TestCursor实例:
def patched_cursor(self, **kwargs): # 忽略所有多余kwargs,创建并返回TestCursor实例 return TestCursor(self) # 使用patch.object替换Connection类的cursor方法 with patch.object(sqlite3.Connection, 'cursor', new=patched_cursor): conn = sqlite3.connect(':memory:') # 现在调用带任意关键字参数的conn.cursor不会报错 cur = conn.cursor(row_factory='foo', any_random_param='bar') print(type(cur)) # 输出 <class '__main__.TestCursor'>
兼容原cursor方法的参数
如果需要保留原cursor方法支持的cursorclass参数,可以修改patched_cursor:
def patched_cursor(self, cursorclass=None, **kwargs): # 优先使用传入的cursorclass,否则用自定义的TestCursor target_cls = cursorclass or TestCursor return target_cls(self)
这样既兼容原方法的参数逻辑,又能忽略额外的关键字参数。
内容的提问来源于stack exchange,提问作者jprockbelly
相关产品推荐
相关产品推荐

