gpt4 book ai didi

python - 继承上下文管理器的pythonic方式是什么

转载 作者:太空狗 更新时间:2023-10-29 17:48:29 25 4
gpt4 key购买 nike

Python 教我们使用 __enter____exit__ 对对象进行清理。如果我需要创建一个使用对象的对象必须使用上下文管理器怎么办?想象一下:

from database1 import DB1
from database2 import DB2

通常,它们会这样使用:

with DB1() as db1, DB2() as db2:
db1.do_stuff()
db2.do_other_stuff()

无论发生什么,db1db2 都将运行它们的 __exit__ 函数,并清理连接、刷新等。

当我将所有这些都放在一个类中时,我会怎么做? 这对吗? 这显然是不对的,db1db2 的上下文管理器在 block 的末尾运行,如注释中所指出的.

class MyApp(object):
def __enter__(self):
with DB1() as self.db1, DB2() as self.db2:
return self
def __exit__(self, type, value, traceback):
self.db1.__exit__(self, type, value, traceback)
self.db2.__exit__(self, type, value, traceback)

我什至考虑过做这样的事情: 这看起来是个好主意,实际上(经过一些清理之后):

class MyApp(object):
def __init__(self):
self.db1 = DB1()
self.db2 = DB2()
def __enter__(self):
self.db1.__enter__()
self.db2.__enter__()
return self
def __exit__(self, type, value, traceback):
try:
self.db1.__exit__(self, type, value, traceback)
except:
pass
try:
self.db2.__exit__(self, type, value, traceback)
except:
pass

编辑:修复了代码。

最佳答案

我会选择第二种解决方案,但也会处理数据库错误:

import sys

class MyApp(object):
def __init__(self):
self.db1 = DB1()
self.db2 = DB2()
def __enter__(self):
self.db1.__enter__()
try:
self.db2.__enter__()
except:
self.db1.__exit__(None, None, None) # I am not sure with None
raise
return self
def __exit__(self, type, value, traceback):
try:
self.db1.__exit__(self, type, value, traceback)
finally:
self.db2.__exit__(self, type, value, traceback)

第一个在 __enter__ 中调用 __exit__ 因为 with - 所以,不起作用。

编辑:另请查看 answer by @Ming .在许多情况下,它更短。

关于python - 继承上下文管理器的pythonic方式是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31189526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com