首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sqlite3的装饰器

Sqlite3的装饰器
EN

Stack Overflow用户
提问于 2021-05-07 21:59:23
回答 1查看 157关注 0票数 0

我有一个简单的sqlite3函数

代码语言:javascript
复制
from sqlite3 import connect


def foo(name):
    conn = connect("data.db")
    curs = conn.cursor()
    curs.execute(f"CREATE TABLE IF NOT EXISTS {name}(test TEXT PRIMARY KEY);")
    conn.commit()
    conn.close()

我想要一个装饰师,这样我就可以写作了。

代码语言:javascript
复制
from sqlite3 import connect

@db_connect
def foo(name):  # Don't know how to pass the args
    curs.execute(f"CREATE TABLE IF NOT EXISTS {name}(test TEXT PRIMARY KEY);")

目标是,我不必获得连接,关闭它,等等。

我尝试过的:

代码语言:javascript
复制
def db_connect(func):
    def _db_connect(*args, **kwargs):
        conn = connect("data.db")
        curs = conn.cursor()
        result = func(*args, **kwargs)
        conn.commit()
        conn.close()
        return result
    return _db_connect

但现在我有点卡住了,因为如何将光标传递给函数,我的装饰器可以工作吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-07 22:25:03

你真正需要的是一个上下文管理器,而不是一个装饰器。

代码语言:javascript
复制
import sqlite3
from contextlib import contextmanager

@contextmanager
def db_ops(db_name):
    conn = sqlite3.connect(db_name)
    cur = conn.cursor()
    yield cur
    conn.commit()
    conn.close()



with db_ops('db_path') as cur:
    cur.execute('create table if not exists temp (id int, name text)')

with db_ops('db_path') as cur:
    rows = [(1, 'a'), (2, 'b'), (3, 'c')]
    cur.executemany('insert into temp values (?, ?)', rows)

with db_ops('db_path') as cur:
    print(list(cur.execute('select * from temp')))

输出

代码语言:javascript
复制
[(1, 'a'), (2, 'b'), (3, 'c')]

正如你所看到的,你不再需要提交或创建连接。

值得注意的是,连接对象在缺省情况下支持上下文管理器协议,这意味着您可以这样做

代码语言:javascript
复制
conn = sqlite3.connect(...)
with conn:
    ...

但这只是提交,它不会关闭连接,您仍然必须使用conn.close()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67436362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档