我尝试手动装饰sqlite3.Connection.execute
但不允许。除了直接装饰sqlite3.Connection
对象本身之外,还有其他方法吗?
我的代码:
db = g._db = sqlite3.connect(app.config['DB_PATH'])
def allow_direct_commit(f_execute):
@functools.wraps(f_execute)
def decorated(*args, **kwargs):
r = f_execute(*args, **kwargs)
r.commit = db.commit
return r
return decorated
db.execute = allow_direct_commit(db.execute)
我的目标是能够做到:
db.execute('whatever').commit()
如果我想代替:
db.execute('whatever')
db.commit()
注意:我正在使用Flask,而不是它应该对此示例有用。
编辑:事实证明,装饰sqlite3.Connection
本身比我想象的更棘手,更糟糕。我还必须使用类似的黑客方法将commit
设置为sqlite3.Cursor
,并且还必须手动添加__iter__
方法。我不知道为什么。我认为__getattribute__
会采取这种做法,但我得到了TypeError: 'Cursor' object is not iterable
。最后,遗憾的是,你不能functools.wraps
一个班级。
如果有人能想出更好的版本,我会很高兴看到它。
db = sqlite3.connect(app.config['DB_PATH'])
def allow_direct_commit(db):
db_execute = db.execute
@functools.wraps(db_execute)
def decorated_execute(*args, **kwargs):
r = db_execute(*args, **kwargs)
class Cursor:
def __getattribute__(self, attr):
if attr == 'commit':
return db.commit
return getattr(r, attr)
def __iter__(self):
return r.__iter__()
return Cursor()
class DB:
def __getattribute__(self, attr):
if attr == 'execute':
return decorated_execute
return getattr(db, attr)
return DB()
db = allow_direct_commit(db)
g._db = db