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。这就是为什么这些方法不会被触发的原因。
很可能我没有完全理解这一点,但我有一个 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。这就是为什么这些方法不会被触发的原因。