python contextlib 关闭阻止 enter/exit 调用

python contextlib closing prevents enter/exit calls

很可能我没有完全理解这一点,但我有一个 class 声明为

class db:
    def __init__(self, name):
        pass
        #self._conn = get_conn(name)
    
    def __enter__(self):
        print('enter')
        #self_conn.begin_transaction()
    def __exit__(self, a, b, c):
        print('exit')
        #self._conn.commit()
    def close(self):
        print('close')
        #self._conn.close()

当我使用它时:

with db('bname') as db:
    print('do something')

我得到了预期的输出:

enter
do something
exit

但是当我使用 contextlib 关闭时,这些函数根本不会被调用

from contextlib import closing

with closing(db('bname')) as db:
    print('do something')

我只得到:

do something
close

我的理解是 contextlib 关闭可以与上下文管理器一起使用 classes 总是调用 close 但我错过了什么?

closing class 实现了自己的 __exit__ 版本。这调用 close().

由于您将 closing 的实例传递给 with 块,关闭实例的 __exit__ 方法将被调用,而不是您的。

Subclass closing class 让你的 __exit__ 被叫到。这是一个例子:

from contextlib import closing


class Db(closing):
    def __init__(self):
        super().__init__(self)
        print('initializing')

    def close(self):
        print('closing')

    def __enter__(self):
        print('entering')

    def __exit__(self, *exc_info):
        print('exiting')
        return super().__exit__(*exc_info)


with Db() as db:
    print('running')

输出

initializing
entering
running
exiting
closing

执行__enter____exit__块的是with statement。在你的第二个例子中,你申请的是 closing 函数,而不是你的 db class。这就是为什么这些方法不会被触发的原因。