Return 文件句柄是用什么打开的?
Return file handles opened with with open?
我正在创建我想要接受压缩文件的软件。由于文件无处不在 read/written,我创建了一个用于打开文件的实用函数,它为我处理 opening/closing 一些压缩文件类型。
示例代码:
def return_file_handle(input_file, open_mode="r"):
""" Handles compressed and uncompressed files. Accepts open modes r/w/w+ """
if input_file.endswith(".gz")
with gzip.open(input_file, open_mode) as gzipped_file_handle:
return gzipped_file_handle
问题是,当使用这段代码时,文件句柄似乎在函数 returns 时关闭。我可以用 with open
做我想做的事,还是我需要自己处理关闭?
将此添加到上面的代码中以获得最小的非工作示例:
for line in return_file_handle(input_bed, "rb"):
print line
创建一个 gzip 文本文件:
echo "hei\nder!" | gzip - > test.gz
错误信息:
Traceback (most recent call last):
File "check_bed_against_blacklist.py", line 26, in <module>
check_bed_against_blacklist("test.gz", "bla")
File "check_bed_against_blacklist.py", line 15, in check_bed_against_blacklist
for line in return_file_handle(input_bed, "r"):
ValueError: I/O operation on closed file.
尝试将其作为生成器:
def return_file_handle(input_file, open_mode="r"):
"""
Handles compressed and uncompressed files. Accepts open modes r/w/w+
"""
# compressed
if input_file.endswith(".gz"):
with gzip.open(input_file, open_mode) as gzipped_file_handle:
yield gzipped_file_handle
else:
with open(input_file, open_mode) as normal_fh:
yield normal_fh
当你调用它时:
for line in return_file_handle("file.gz"):
print(line.read())
或者使用 python's new yield from
syntax:
组成一个生成器
def each_line(fh):
for l in fh:
yield from l
并调用它:
for each in each_line(return_file_handle(fh)):
print(each)
文件在 for 循环结束时完全关闭。
您用于打开文件的样式会在块末尾自动将其关闭。这就是 with
打开文件的块样式的全部意义。
您想做的是:
gzipped_file_handle = gzip.open(input_file, open_mode)
return gzipped_file_handle
注意:您只需要注意在调用此函数后关闭文件即可。
我能想到的最好的方法是传递一个函数作为接受打开的 fd 的参数:
def work(fd):
for line in fd:
print line
def work_with_file_handle(input_file, func, open_mode="r"):
if input_file.endswith(".gz")
with gzip.open(input_file, open_mode) as gzipped_file_handle:
func(gzipped_file_handle)
work_with_file_handle('xxx.gz', work)
避免使用,如果你想 return file_handle。因为file_handle会在with块执行完后自动关闭
您应该使用以下代码:
import gzip
def return_file_handle(input_file, open_mode="rb"):
if input_file.endswith(".gz"):
gzipped_file_handle = gzip.open(input_file, open_mode)
return gzipped_file_handle
for line in return_file_handle('file.txt.gz', "r"):
print line
我会使用另一个上下文管理器
from contextlib import contextmanager
@contextmanager
def return_file_handle(input_file, open_mode="r"):
""" Handles compressed and uncompressed files. Accepts open modes r/w/w+ """
if input_file.endswith(".gz")
with gzip.open(input_file, open_mode) as gzipped_file_handle:
yield gzipped_file_handle
else:
with open(input_file, open_mode) as normal_file:
yield normal_file
# Your file will be closed after this
with return_file_handle(file_name, mode) as f:
pass
我正在创建我想要接受压缩文件的软件。由于文件无处不在 read/written,我创建了一个用于打开文件的实用函数,它为我处理 opening/closing 一些压缩文件类型。
示例代码:
def return_file_handle(input_file, open_mode="r"):
""" Handles compressed and uncompressed files. Accepts open modes r/w/w+ """
if input_file.endswith(".gz")
with gzip.open(input_file, open_mode) as gzipped_file_handle:
return gzipped_file_handle
问题是,当使用这段代码时,文件句柄似乎在函数 returns 时关闭。我可以用 with open
做我想做的事,还是我需要自己处理关闭?
将此添加到上面的代码中以获得最小的非工作示例:
for line in return_file_handle(input_bed, "rb"):
print line
创建一个 gzip 文本文件:
echo "hei\nder!" | gzip - > test.gz
错误信息:
Traceback (most recent call last):
File "check_bed_against_blacklist.py", line 26, in <module>
check_bed_against_blacklist("test.gz", "bla")
File "check_bed_against_blacklist.py", line 15, in check_bed_against_blacklist
for line in return_file_handle(input_bed, "r"):
ValueError: I/O operation on closed file.
尝试将其作为生成器:
def return_file_handle(input_file, open_mode="r"):
"""
Handles compressed and uncompressed files. Accepts open modes r/w/w+
"""
# compressed
if input_file.endswith(".gz"):
with gzip.open(input_file, open_mode) as gzipped_file_handle:
yield gzipped_file_handle
else:
with open(input_file, open_mode) as normal_fh:
yield normal_fh
当你调用它时:
for line in return_file_handle("file.gz"):
print(line.read())
或者使用 python's new yield from
syntax:
def each_line(fh):
for l in fh:
yield from l
并调用它:
for each in each_line(return_file_handle(fh)):
print(each)
文件在 for 循环结束时完全关闭。
您用于打开文件的样式会在块末尾自动将其关闭。这就是 with
打开文件的块样式的全部意义。
您想做的是:
gzipped_file_handle = gzip.open(input_file, open_mode)
return gzipped_file_handle
注意:您只需要注意在调用此函数后关闭文件即可。
我能想到的最好的方法是传递一个函数作为接受打开的 fd 的参数:
def work(fd):
for line in fd:
print line
def work_with_file_handle(input_file, func, open_mode="r"):
if input_file.endswith(".gz")
with gzip.open(input_file, open_mode) as gzipped_file_handle:
func(gzipped_file_handle)
work_with_file_handle('xxx.gz', work)
避免使用,如果你想 return file_handle。因为file_handle会在with块执行完后自动关闭
您应该使用以下代码:
import gzip
def return_file_handle(input_file, open_mode="rb"):
if input_file.endswith(".gz"):
gzipped_file_handle = gzip.open(input_file, open_mode)
return gzipped_file_handle
for line in return_file_handle('file.txt.gz', "r"):
print line
我会使用另一个上下文管理器
from contextlib import contextmanager
@contextmanager
def return_file_handle(input_file, open_mode="r"):
""" Handles compressed and uncompressed files. Accepts open modes r/w/w+ """
if input_file.endswith(".gz")
with gzip.open(input_file, open_mode) as gzipped_file_handle:
yield gzipped_file_handle
else:
with open(input_file, open_mode) as normal_file:
yield normal_file
# Your file will be closed after this
with return_file_handle(file_name, mode) as f:
pass