It is a good practice to use the with
statement when opening a file in Python. However, opening variable files at the same time with this syntax is not straightforward. Of course, it doesn't work even if I write it like this.
with [open(fn) for fn in file_names] as files:
For example, when performing processing such as the paste command, simultaneous open is absolutely necessary. So, in this article, I'll write about how to use the with
statement to achieve behavior like the paste command in Python.
fileopen
module (Reference: [How to read text by standard input or file name specification like cat in Python](https://qiita.com/hi- asano / items / 010e7e3410ea4e1486cb)).with open (a) as f1, open (b) as f2:
etc.paste.py
import argparse
import contextlib
def main():
parser = argparse.ArgumentParser()
parser.add_argument('fs', nargs='*', type=argparse.FileType(),
default='-')
parser.add_argument('--delimiter', default='\t')
args = parser.parse_args()
with contextlib.ExitStack() as stack:
for f in args.fs:
stack.enter_context(f)
paste(args.fs, args.delimiter)
if __name__ == "__main__":
main()
The behavior when type = argparse.FileType (), default ='-'
is specified in ʻadd_argument ()is [this article](https://qiita.com/hi-asano/items/010e7e3410ea4e1486cb) As you can see in. And this time, by combining it with
nargs ='*'`, you can get a list of file objects from variable command line arguments.
And what I want to convey most is the part of this with
sentence. In the first place, the with statement is used to wrap the execution of a block with the method of "context manager". And the module to easily implement this context manager type is contextlib.
To handle variable files with a with
statement like this one, first create a context manager with ʻExitStack () and add the objects you want to manage with ʻenter_context ()
. With this, close is called firmly when exiting the with block.
Deviating from the purpose of this article, here is an implementation example of paste ()
.
from itertools import zip_longest
def rstrip(x):
if x is None:
return ''
else:
return x.rstrip()
def paste(files, delimiter):
for lines in zip_longest(*files):
stripped = map(rstrip, lines)
print(delimiter.join(stripped))
Q13 of 100 language processing knocks is also OK with this code
Recommended Posts