Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python 2.7中使用列表理解的多个with语句 问题:_Python_Python 2.7_List Comprehension_With Statement - Fatal编程技术网

在Python 2.7中使用列表理解的多个with语句 问题:

在Python 2.7中使用列表理解的多个with语句 问题:,python,python-2.7,list-comprehension,with-statement,Python,Python 2.7,List Comprehension,With Statement,我感兴趣的是使用语句在Python中进行列表理解,这样我就可以用最少的语法同时打开多个上下文管理器。我正在寻找与Python 2.7兼容的答案 考虑下面的代码示例。我想同时对任意长的列表中的变量使用with语句,最好是以语法清晰的方式 def do_something(*args): contexts = {} with [open(arg) as contexts[str(i)] for i, arg in enumerate(args)]: do_anothe

我感兴趣的是使用语句在Python
中进行列表理解,这样我就可以用最少的语法同时打开多个上下文管理器。我正在寻找与Python 2.7兼容的答案

考虑下面的代码示例。我想同时对任意长的列表中的变量使用
with
语句,最好是以语法清晰的方式

def do_something(*args):
    contexts = {}
    with [open(arg) as contexts[str(i)] for i, arg in enumerate(args)]:
        do_another_thing(contexts)

do_something("file1.txt", "file2.txt")
有人知道在Python2.7中的
with
语句中是否有一种包含列表理解的方法吗


对类似问题的答复: 以下是我已经看过的一些东西,并解释了为什么它们不适合我的目的:

对于Python2.6-,我可以使用
contextlib.nested
来实现这一点,类似于:

def do_something(*args):
    contexts = {}
    with nested(*[open(arg) for arg in args]) as [contexts[str(i)] for i in range(len(args))]:
        do_another_thing(contexts)
然而,这在Python 2.7+
中是不推荐的,所以我认为使用它是不好的做法

相反,在上给出了新语法,以及:

但是,我需要能够处理任意的输入列表,如我上面给出的示例所示。这就是为什么我喜欢列表理解

对于Python 3.3+,描述了如何使用
ExitStack
实现这一点。但是,我使用的是Python 2.7

也有,但我宁愿不写我自己的类来完成这一点

在Python2.7中,是否有希望将列表理解和
语句与
语句结合起来

更新1-3:更新示例以更好地强调我正在寻找的功能


更新4:找到另一个。这个问题的答案也表明了
ExitStack
,这是一个在2.7中不可用的函数。

带有
语句的
的主要任务是调用其上下文管理器的
\uuuuuuu退出
属性。专门处理文件。因此,在这种情况下,由于这一点以及
open()
返回
file\u对象的事实,您可以使用列表理解来创建文件对象的列表,只需手动调用
exit()/close()
。但是请注意,在这种情况下,您必须手动处理异常

def print_files(*args):
    f_objs = [open(arg) for arg in args]
    # do what you want with f_objs
    # ...
    # at the end
    for obj in f_objs:
        f.close()
请注意,如果您只想在文件对象上运行一些并行操作,我建议使用这种方法,否则最好的方法是在for循环中使用
with
语句,并在每次迭代中打开文件(在名称上),如下所示:

for arg in args:
    with open(arg) as f:
         # Do something with f
为了更安全,您也可以使用自定义的
打开
功能来处理异常:

def my_open(*args, **kwargs):
    try:
        file_obj = open(*args, **kwargs)
    except Exception as exp:
        # do something with exp and return a proper object
    else:
        return file_obj

def print_files(*args):
    f_objs = [my_open(arg) for arg in args]
    # do what you want with f_objs
    # ...
    # at the end
    for obj in f_objs:
        try:
            f.close()
        except Exception as exp:
            # handle the exception

自己做这件事真的很棘手,尤其是处理打开或关闭文件时发生的异常。我建议只获得一个实现
contextlib.ExitStack
功能的库。那你就可以了

with contextlib2.ExitStack() as stack:
    files = [stack.enter_context(open(arg)) for arg in args]
    ...

就像您使用Python 3中的
contextlib.ExitStack
一样,一切都得到了正确的处理。

这就像是一个“我有
ship1=1;ship2=2
代码,现在我想要无限数量的ship,我如何在代码中用新的数字创建ship变量???这可能吗?”毫无意义的问题。循环使用with语句<代码>对于列表中的项:将open(item)作为f:f.read()
…我需要能够同时打开所有上下文管理器,例如,
将open(item1)作为f1:将open(item2)作为f2:#对两者都做些什么。我也有任意数量的项目。更新了我的示例,以显示上下文管理器需要如何同时打开,而不仅仅是按顺序打开。这没有
ExitStack
的异常安全好处,尤其是在打开其中一个文件失败时。@user2357112确实,还有
exit()期间的异常
。感谢您的回答@Kasramvd。不幸的是,正如@user2357112所指出的,您的示例没有使用
所带来的安全好处,这正是我想要的。是的,我希望做一些与物体平行的事情。@Miles是的,这是一个很好的观点。在这种情况下,我认为你必须像退出那样手动操作。可能使用装饰器或其他功能,检查编辑。如果在打开和关闭之间发生异常,您不会关闭文件;最后你需要试一下。另外,与手动处理相比,
ExitStack
的一个主要优点是,它允许您干净地传播安装或拆卸过程中发生的异常。对于手动处理,传播它们而不是使它们沉默是非常尴尬的。谢谢@user2357112-这绝对是解决我问题的好办法。但是,我想在Python2.7本身中使用一些东西,而不必导入外部库。但是,如果没有这样的答案,我将接受你的答案!
with contextlib2.ExitStack() as stack:
    files = [stack.enter_context(open(arg)) for arg in args]
    ...