Python 返回用open打开的文件句柄?
我正在创建我想要接受压缩文件的软件。由于文件在任何地方都是读/写的,所以我创建了一个实用程序函数来打开文件,它为我处理一些压缩文件类型的打开/关闭 示例代码:Python 返回用open打开的文件句柄?,python,with-statement,Python,With Statement,我正在创建我想要接受压缩文件的软件。由于文件在任何地方都是读/写的,所以我创建了一个实用程序函数来打开文件,它为我处理一些压缩文件类型的打开/关闭 示例代码: 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")
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
问题是,在使用此代码时,当函数返回时,文件句柄似乎关闭。我可以用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.
回溯(最近一次呼叫最后一次):
文件“对照黑名单检查床”,第26行,在
对照黑名单(“test.gz”、“bla”)检查
文件“check_bed_from_blacklist.py”,第15行,check_bed_from_blacklist.py
对于返回文件句柄中的行(输入“r”):
ValueError:对关闭的文件执行I/O操作。
尝试将其作为生成器:
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())
或者使用
并称之为:
for each in each_line(return_file_handle(fh)):
print(each)
文件在for循环结束时完全关闭。用于打开文件的样式将在块结束时自动关闭文件。这就是打开文件的
块样式的全部要点
您要做的是:
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)
如果要返回文件句柄,请避免使用。因为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
那很酷。我不知道python中的生成器有多容易。我最喜欢这个答案,因为一旦你读完它,它会为你关闭文件。小心——这可能不是你想的那样。“return\u file\u handle”将生成器返回到文件,而不是返回到行,因此写入的for循环只运行一次。意思是如果您想逐行处理它:for file in return\u file\u handle(“file.gz”):for line in file.readlines():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