我可以在python中使用带有列表的语句吗?

时间:2014-11-12 03:32:22

标签: python exception exception-handling with-statement

当我处理一个文件时,我可以使用with语句来确保它在成功或失败时始终关闭。如

with open('some_file', 'r') as f:
    print f.read()

但是,我现在需要打开一个文件列表,其数量仅在运行时已知,因此我不能使用嵌套的语句。但是我可以将它与列表一起使用吗?有点像

with [open(fn) for fn in file_names] as files:
     #do something

以上显然不起作用。什么会起作用?

2 个答案:

答案 0 :(得分:1)

这正是contextlib模块的contextlib.nested管理器的设计目标。您可以像这样使用它:

from contextlib import nested

with nested(*[open(fn) for fn in file_names]) as files:
    # files is a list of file objects

但请注意,正如documentation中所述,自Python2.7以来,该函数已被弃用,原因有两个怪癖。我会让你判断你是否可以在你想到的应用程序中与他们一起生活。

我认为这也是提及with声明解释here的鲜为人知的多管理员表单的好时机。即使它不适用于您的情况,我认为知道它存在是很好的。

答案 1 :(得分:1)

正如@Marcin在评论中提到的那样,我认为没有办法使用列表with来实现这一点。

但是,对于一组允许封装的try / except / finally块,with基本上是语法糖,因此更容易重用。

虽然您可以在单个with中指定多个配对,即

with open('foo.txt', 'r') as f, open('bar.txt', 'r') as f2:
    pass    # do stuff here

动态变量没有允许,例如list s或tuple s。实际上,此表单被视为以逗号分隔的表达式嵌套with s。

但是,您可以做的事实上是忽略with语法糖,并依赖于它要替换的原始语法。也就是说,将您的逻辑封装在一组try / except / finally块中。这样,您可以在运行时打开文件列表,然后通过finally子句确保它们得到清理。

某种形式:

try:
    files = [open(fn) for fn in file_names]

    # do stuff with files
except:
    # handle exceptions as needed here
finally:
    for f in files:
        f.close();

    # and any other cleanup you want to do