Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 返回用open打开的文件句柄?_Python_With Statement - Fatal编程技术网

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