为什么不“尝试,除了”在python中使用经典的“open(fname,'r')”?

时间:2016-01-24 15:09:46

标签: python file exception-handling

我有一个打开文件并返回打开的file对象的函数。

def read_any():
    try:
        opened = gzip.open(fname, 'r')
    except IOError:
        opened = open(fname, 'r')
    return opened

当我尝试在某个非压缩文件except上运行此函数时,状态不会被触发,并且该函数会崩溃并显示消息:IOError: Not a gzipped file

好的,现在我尝试用with语句做同样的事情:

def read_any2():
    try:
        with gzip.open(fname, 'r') as f:
            return f.read()
    except IOError:
        with open(fname, 'r') as f:
            return f.read()

现在,如果我尝试运行相同的文件,该功能将按预期工作。 你能解释为什么except条件不会被触发吗?

1 个答案:

答案 0 :(得分:2)

要了解发生了什么,请在REPL中进行测试:

>>> import gzip
>>> f = gzip.open('some_nongzipped_file', 'r')

您将看到这不会引发错误。但是,一旦你从对象中读取:

>>> f.read()
... (snip)
OSError: Not a gzipped file

,它引发了错误。

简而言之:简单地创建文件对象不会从文件中读取任何内容,因此不知道它是否应该失败。

因为在第一个示例中,您只返回文件对象,当您稍后尝试从中读取时,它将在那里引发异常(在raise-except块之外)。在第二个示例中,您返回f.read(),它会读取并因此引发异常。它与with块无关,如你删除它可以看到:

def read_any_mod():
    try:
        opened = gzip.open(fname, 'r')
        return opened.read()
    except IOError:
        opened = open(fname, 'r')
        return opened.read()