如何在 with 语句中有多个虚拟文件编写器?
How to have multiple dummy file writers in a with statement?
我阅读 this answer of Is it possible to have an optional with/as statement in python? that you can have a dummy file writer with contextmanager
。但是,我想在 with 语句上下文中打开多个虚拟文件编写器。
假设我创建了两个虚拟文件:touch a
和 touch b
.
鉴于脚本的第一部分:
#!/usr/bin/python
from contextlib import contextmanager
# File names
fa="a"
fb="b"
# Dummy file handler
none_context = contextmanager(lambda: iter([None]))()
此添加适用于单个虚拟文件编写器(它打印 2
):
printing=False
with (open(fa) if printing else none_context) as writter:
print 1 if printing else 2
这也有效,因为我们确实在读取文件(它打印 1
):
printing=True
with (open(fa, "r") if printing else none_context) as writter, \
(open(fb, "r") if printing else none_context) as another_writter:
print 1 if printing else 2
但是,如果我们使用两个虚拟文件编写器,它就不起作用:
printing=False
with (open(fa, "r") if printing else none_context) as writter, \
(open(fb, "r") if printing else none_context) as another_writter:
print 1 if printing else 2
显示错误:
Traceback (most recent call last):
File "dummy_opener.py", line 23, in <module>
with (open(fa, "r") if printing else none_context) as writter, \
File "/usr/lib64/python2.7/contextlib.py", line 19, in __enter__
raise RuntimeError("generator didn't yield")
RuntimeError: generator didn't yield
为什么会这样?还有:我怎样才能使这个多个 with open
命令与虚拟文件编写器一起工作?
您的代码失败,因为您已经在第一次调用时使用了迭代器,如果您在 with 块中调用 none_context()
,原始代码将起作用:
none_context = contextmanager(lambda: iter([None]))
printing=False
with open(fa, "r") if printing else none_context() as writter, \
open(fb, "r") if printing else none_context() as another_writter:
print 1 if printing else 2
你可以看到使用你的原始代码,如果你为每个打开添加一个 None
那么代码将按预期工作:
none_context = contextmanager(lambda: iter([None,None,None]))()
printing=False
with open(fa, "r") if printing else none_context as writter, \
open(fb, "r") if printing else none_context as another_writter,\
open(fb, "r") if printing else none_context as another_writer3:
print 1 if printing else 2
我阅读 this answer of Is it possible to have an optional with/as statement in python? that you can have a dummy file writer with contextmanager
。但是,我想在 with 语句上下文中打开多个虚拟文件编写器。
假设我创建了两个虚拟文件:touch a
和 touch b
.
鉴于脚本的第一部分:
#!/usr/bin/python
from contextlib import contextmanager
# File names
fa="a"
fb="b"
# Dummy file handler
none_context = contextmanager(lambda: iter([None]))()
此添加适用于单个虚拟文件编写器(它打印 2
):
printing=False
with (open(fa) if printing else none_context) as writter:
print 1 if printing else 2
这也有效,因为我们确实在读取文件(它打印 1
):
printing=True
with (open(fa, "r") if printing else none_context) as writter, \
(open(fb, "r") if printing else none_context) as another_writter:
print 1 if printing else 2
但是,如果我们使用两个虚拟文件编写器,它就不起作用:
printing=False
with (open(fa, "r") if printing else none_context) as writter, \
(open(fb, "r") if printing else none_context) as another_writter:
print 1 if printing else 2
显示错误:
Traceback (most recent call last):
File "dummy_opener.py", line 23, in <module>
with (open(fa, "r") if printing else none_context) as writter, \
File "/usr/lib64/python2.7/contextlib.py", line 19, in __enter__
raise RuntimeError("generator didn't yield")
RuntimeError: generator didn't yield
为什么会这样?还有:我怎样才能使这个多个 with open
命令与虚拟文件编写器一起工作?
您的代码失败,因为您已经在第一次调用时使用了迭代器,如果您在 with 块中调用 none_context()
,原始代码将起作用:
none_context = contextmanager(lambda: iter([None]))
printing=False
with open(fa, "r") if printing else none_context() as writter, \
open(fb, "r") if printing else none_context() as another_writter:
print 1 if printing else 2
你可以看到使用你的原始代码,如果你为每个打开添加一个 None
那么代码将按预期工作:
none_context = contextmanager(lambda: iter([None,None,None]))()
printing=False
with open(fa, "r") if printing else none_context as writter, \
open(fb, "r") if printing else none_context as another_writter,\
open(fb, "r") if printing else none_context as another_writer3:
print 1 if printing else 2