Multiple variables in a 'with' statement?
是否可以在Python中使用
就像是:
1 2 3 4 5 | from __future__ import with_statement with open("out.txt","wt"), open("in.txt") as file_out, file_in: for line in file_in: file_out.write(line) |
......还是正在清理两个资源同时出现问题?
从v3.1和Python 2.7开始,它可以在Python 3中实现。新的
1 2 | with A() as a, B() as b, C() as c: doSomething(a,b,c) |
与
1 2 3 4 5 | import contextlib with contextlib.nested(open("out.txt","wt"), open("in.txt")) as (file_out, file_in): ... |
更新:
引用文档,关于
Deprecated since version 2.7: The with-statement now supports this
functionality directly (without the confusing error prone quirks).
看拉法? Dowgird的回答是为了获取更多信息。
请注意,如果将变量拆分为行,则必须使用反斜杠来换行换行符。
1 2 3 4 | with A() as a, \ B() as b, \ C() as c: doSomething(a,b,c) |
括号不起作用,因为Python会创建一个元组。
1 2 3 4 | with (A(), B(), C()): doSomething(a,b,c) |
由于元组缺少
1 AttributeError: __enter__
如果您尝试在括号内使用
1 2 3 4 | with (A() as a, B() as b, C() as c): doSomething(a,b,c) |
SyntaxError: invalid syntax
https://bugs.python.org/issue12782似乎与此问题有关。
我想你想这样做:
1 2 3 4 5 6 | from __future__ import with_statement with open("out.txt","wt") as file_out: with open("in.txt") as file_in: for line in file_in: file_out.write(line) |
从Python 3.3开始,您可以使用
它可以管理动态数量的上下文感知对象,这意味着如果您不知道要处理多少文件,它将特别有用。
文档中提到的规范用例是管理动态数量的文件。
1 2 3 4 5 | with ExitStack() as stack: files = [stack.enter_context(open(fname)) for fname in filenames] # All opened files will automatically be closed at the end of # the with statement, even if attempts to open files later # in the list raise an exception |
这是一个通用的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | from contextlib import ExitStack class X: num = 1 def __init__(self): self.num = X.num X.num += 1 def __repr__(self): cls = type(self) return '{cls.__name__}{self.num}'.format(cls=cls, self=self) def __enter__(self): print('enter {!r}'.format(self)) return self.num def __exit__(self, exc_type, exc_value, traceback): print('exit {!r}'.format(self)) return True xs = [X() for _ in range(3)] with ExitStack() as stack: print(stack._exit_callbacks) nums = [stack.enter_context(x) for x in xs] print(stack._exit_callbacks) print(stack._exit_callbacks) print(nums) |
输出:
1 2 3 4 5 6 7 8 9 10 | deque([]) enter X1 enter X2 enter X3 deque([<function ExitStack._push_cm_exit.<locals>._exit_wrapper at 0x7f5c95f86158>, <function ExitStack._push_cm_exit.<locals>._exit_wrapper at 0x7f5c95f861e0>, <function ExitStack._push_cm_exit.<locals>._exit_wrapper at 0x7f5c95f86268>]) exit X3 exit X2 exit X1 deque([]) [1, 2, 3] |