gpt4 book ai didi

Python - with 带有可选对象的语句

转载 作者:行者123 更新时间:2023-11-28 22:38:34 24 4
gpt4 key购买 nike

我有一个处理一些数据的脚本,如果存在数据库/文件,则将一些数据写入其中。我将数据库或文件指定为 configargparse(argparse) 参数。我需要以某种有组织的方式清理(关闭文件,数据库)以防发生异常。

这是我的初始化:

import sqlite3
import confargparse
import sys
parser.ArgParser(...)
parser.add('--database', dest='database',
help='path to database with grabbers', metavar='FILE',
type=lambda x: arghelper.is_valid_file(parser, x))
parser.add('-f', '--file', type=configargparse.FileType(mode='r'))
args = parser.parse_args()

我使用 iftry 做到了这一点:

if args.database:
conn = sqlite3.connect(args.database)
c = conn.cursor()
# same init for file

try:
while True: # do something, it might be moved to some main() function
result = foo()
if args.database:
c.execute('Write to database {}'.format(result))
# same
# for file
finally:
if args.database:
conn.close()
# same
# for file
except KeyboardInterrupt:
print 'keyboard interrupt'

可以用with语句来完成吗?类似于(来自 C 的 ()?():()):

with ((args.database)?
(conn = sqlite3.connect(args.database)):
(None)) as db, same for file:

然后在with 子句中引用数据库并检查它们是否存在?

最佳答案

先回答你的问题。可以使用 contextlib 来完成。但我不确定您会从中获得多少 yield 。

from contextlib import contextmanager

@contextmanager
def uncertain_conn(args):
yield sqlite3.connect(args.database) if args.database else None

# Then you use it like this
with uncertain_conn(args) as conn:
# conn will be the value yielded by uncertain_conn(args)
if conn is not None:
try:
# ...

但正如我所说,虽然将生成器函数转换为上下文管理器很酷,而且我个人非常喜欢 contextmanager 装饰器,它确实为您提供了您想要的功能,但我不不知道它在这里是否真的对您有很大帮助。如果我是你,我可能会对 if 感到满意:

if args.database:
conn = sqlite3.connect(args.database)
try:
# ...

不过,一些您可以使用 with 简化的事情。查看 closing,也来自 contextlib(非常简单,我将只引用文档):

contextlib.closing(thing)

Return a context manager that closes thing upon completion of the block. This is basically equivalent to:

from contextlib import contextmanager

@contextmanager def closing(thing):
try:
yield thing
finally:
thing.close()

所以上面的代码可以变成:

if args.database:
conn = sqlite3.connect(args.database)
with closing(conn):
# do something; conn.close() will be called no matter what

但这不会为 KeyboardInterrupt 打印一条好消息。如果你真的需要它,那么我想你仍然必须自己写出 try-except-finally。做任何更奇特的事情可能都不值得。 (注意 except 必须在 finally 之前,否则会出现语法错误。)

您甚至可以使用 suppress 来做到这一点(但需要谨慎;见下文)

from contextlib import suppress

with suppress(TypeError):
conn = sqlite3.connect(args.database or None)
with closing(conn):
# do business

with suppress(error): do_thing 等价于

try:
do_thing
except error:
pass

因此,如果 args.database 的计算结果为 False,则第二行实际上是 connect(None),这会引发 TypeError ,它将被上下文管理器捕获,下面的代码将被跳过。但风险在于它会抑制其范围内的所有 TypeError,而您可能不希望这样。

关于Python - with 带有可选对象的语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35480918/

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