puf*_*ish 347 python with-statement
是否可以使用withPython中的语句声明多个变量?
就像是:
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)
Run Code Online (Sandbox Code Playgroud)
......还是正在清理两个资源同时出现问题?
Raf*_*ird 607
从v3.1和 Python 2.7 开始,它可以在Python 3中实现.新with语法支持多个上下文管理器:
with A() as a, B() as b, C() as c:
doSomething(a,b,c)
Run Code Online (Sandbox Code Playgroud)
不同的是contextlib.nested,这保证了a和b将他们__exit__()的调用,即使C()或者它的__enter__()方法抛出一个异常.
Ale*_*lli 56
contextlib.nested 支持这个:
import contextlib
with contextlib.nested(open("out.txt","wt"), open("in.txt")) as (file_out, file_in):
...
Run Code Online (Sandbox Code Playgroud)
更新:
引用文档,关于contextlib.nested:
从版本2.7开始不推荐使用:with语句现在直接支持此功能(没有令人困惑的容易出错的怪癖).
有关更多信息,请参阅RafałFowgird的答案.
jim*_*qaz 29
请注意,如果将变量拆分为行,则必须使用反斜杠来换行换行符.
with A() as a, \
B() as b, \
C() as c:
doSomething(a,b,c)
Run Code Online (Sandbox Code Playgroud)
括号不起作用,因为Python会创建一个元组.
with (A(),
B(),
C()):
doSomething(a,b,c)
Run Code Online (Sandbox Code Playgroud)
由于元组缺少__enter__属性,因此会出现错误(无法识别并且不识别类类型):
Run Code Online (Sandbox Code Playgroud)AttributeError: __enter__
And*_*are 18
我想你想这样做:
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)
Run Code Online (Sandbox Code Playgroud)
因为Python 3.3,你可以使用类ExitStack从contextlib模块.
它可以管理动态数量的上下文感知对象,这意味着如果您不知道要处理多少文件,它将特别有用.
文档中提到的规范用例是管理动态数量的文件.
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
Run Code Online (Sandbox Code Playgroud)
这是一个通用的例子:
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)
Run Code Online (Sandbox Code Playgroud)
输出:
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]
Run Code Online (Sandbox Code Playgroud)
从 Python 3.10 开始,有一个新功能括号上下文管理器,它允许以下语法:
with (
A() as a,
B() as b
):
do_something(a, b)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
106403 次 |
| 最近记录: |