python - 屈服于 block 内部保持打开的 postgres 连接

标签 python generator psycopg2

何时 yield从下面的生成器中,postgres 连接是否保持事件状态或者yield需要减少缩进,以便在每个 next() 上建立一个新连接?

def getData(start, end):
    with psycopg2.connect("dbname='test' user='user' host='localhost' password='password'") as conn:
        time = start
        while time<end:
            with conn.cursor() as cur:
                cur.execute(query.format(start, time))
                data = cur.fetchall()
            time += one_week
            yield data

最佳答案

是的,上下文管理器保持事件状态。 yield 暂停函数,没有退出。

yield 不会改变函数内部的执行顺序。该函数只是“暂停”,卡住在 yield 表达式执行并产生值的位置。当生成器稍后恢复时(通过在迭代器上调用__next__),该函数将再次在该点继续。当生成器暂停时,无法调用 with 语句 __exit__ 方法,因此在生成器暂停之前,上下文管理器无法退出不管怎样,还是恢复了。

如果您使用@contextmanager decorator创建一个简单的上下文管理器,您就会看到这种情况发生。 (本身依赖于生成器来实现!):

import sys
from contextlib import contextmanager

@contextmanager
def loud_contextmanager():
    print("Context entered!")
    try:
        yield "value to bind the 'as' target to"
    finally:
        exc_info = sys.exc_info()
        if exc_info:
            print("Context exited with an exception!", exc_info)
        else:
            print("Context exited!")

def generator_stages():
    yield "First yield, outside of a context manage"
    with loud_contextmanager() as cm_as_value:
        yield f"Inside of the with block, received {cm_as_value}"
    yield "Outside of with block, last yield"

当您从生成器中提取值进行打印时,您将看到以下内容:

>>> gen = generator_stages()
>>> print(next(gen))
First yield, outside of a context manage
>>> print(next(gen))
Context entered!
Inside of the with block, received value to bind the 'as' target to
>>> print(next(gen))
Context exited with an exception! (None, None, None)
Outside of with block, last yield
>>> next(gen, "generator was done")
'generator was done'

请注意,在我们检索到第三个值之前,上下文不会退出!在第二次 next() 调用之后,代码会在 with block 内的某个点暂停,只有在取消暂停时才能退出上下文,并且 finally 可以运行 loud_contextmanager() 函数套件。

关于python - 屈服于 block 内部保持打开的 postgres 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54131499/

相关文章:

python - 在 sql 查询 python 中使用时,格式选项不起作用

python - 使用 psycopg 时表格不会改变

python - IronPython + XNA 是游戏开发的有力竞争者吗?

python - 如何知道scrapy规则提取了哪些链接

c++ - 等效于 C++ 到 Python 生成器模式

python - 使用缓冲区通过pandas写入psycopg3复制结果

python - numpy 将 int 解析为位分组

python - 如何获取由 float 组成的范围列表?

javascript - 创建单词查找网格

python - 将 Python 生成器解压为参数——内存效率高吗?