在 __exit__ 中获取 __enter__ 的 return 值

Get __enter__'s return value in __exit__

我正在尝试使数据库连接池的行为类似于简单连接 (psycopg2)。有点像这样:

from psycopg2.pool import ThreadedConnectionPool    
pool = ThreadedConnectionPool(...)
with pool as conn:
    with conn.cursor() as cur:
        # do sql stuff
        ...

为此,我们应该 conn = pool.getconn() 从池中取出,并且在完成查询后,pool.putconn(conn) 将其返回。似乎是使用上下文管理器的完美示例。

然而如果我们这样做:

# this function -> a part of ThreadedConnectionPool subclass
def __enter__(self):
    return self._pool.getconn()  # doesn't return self, returns a database connection

然后,您需要在__exit__方法中return连接。类似于:

# this function -> a part of ThreadedConnectionPool subclass
def __exit__(self, *args):
    self._pool.putconn(conn)  # <--- here!
    ...

但是我们如何访问 conn 对象呢?看起来应该是上下文知道的,但实际上在哪里可以访问?

我读过this SO question,但是这个对象是在多线程环境中使用的,并且同时存储了很多连接,所以我们不可能使用局部状态变量,是吗?

如何访问 __exit__ 函数调用中的 __enter__ return 值?

这个特定对象一次只能有一个连接。所以这应该有效:

    def __enter__(self):
        self.conn = self.__pool.getconn()
        return self.conn
    def __exit__(self, *args):
        self.__pool.putconn(self.conn)
        self.conn = None