gpt4 book ai didi

python - 可以使用 with 语句进行条件执行和终结

转载 作者:太空宇宙 更新时间:2023-11-03 18:08:28 24 4
gpt4 key购买 nike

我有一个非常常见的代码模式,如下所示:

if not resource.hasInstallTag(tag="mysoftwareservice", version="5"):
doX()
doY()
frobnicate()
do()
installMySoftwareService()

resource.recordInstallTag(tag="mysoftwareservice", version="5")

但是,很容易在一个位置更新版本字符串,而忘记在另一个位置执行此操作,或者忘记添加对 recordInstallTag 的调用。

我想要类似以下模式的东西:

with InstallTag(resource, tag, version):
doX()
installTheThingThat(version)
doY()
frobnicate()

地点:

  • 如果资源已经将 tag==tag 安装到 version==version,则跳过内部语句 block 的内容(不引发异常)
  • (仅)如果内部语句 block 无异常成功,则记录此版本的此项已安装到此资源。

例如,类似:

class TagAlreadySetException(Exception):
pass

class InstallTag(object):
def __init__(self, resource, tag, version):
self.resource = resource
self.tag = tag
self.version = version

def __enter__(self):
if self.resource.hasInstallTag(self.tag, self.version):
# Prevent execution of statement block
raise TagAlreadySetException()
return None

def __exit__(self, type, value, tb):
if type==None:
self.resource.recordInstallTag(self.tag, self.version)

不幸的是,虽然引发 TagAlreadySetException 会阻止语句 block 的执行,但它也会继续在调用堆栈中抛出异常。我想捕获 TagAlreadySetException 并处理它。我可以在语句 block 周围没有额外的额外机制的情况下执行此操作吗?

我意识到我可以通过尝试...终于做到这一点。但是,我试图确保标签和项目仅在应用模式时写入一次(以防止不一致)

最佳答案

这是一个简洁的小迪迪:

import contextlib

def manager_gen(resource, tag, version):
def check():
check.called = True
if resource.hasInstallTag(tag, version):
raise TagAlreadySetException

check.called = False

try:
yield check
except TagAlreadySetException:
pass
finally:
if not check.called:
raise RuntimeError("check wasn't called!")

InstallTag = contextlib.contextmanager(manager_gen)

你可以像这样使用它:

with InstallTag as checker:
checker()
raz_the_jazz_and_other_neat_statements()

如果你忘记运行检查,它会在 block 的末尾对你大喊大叫(这可能有用,也可能没用......)

关于python - 可以使用 with 语句进行条件执行和终结,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26413787/

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