为什么';";试试看,除了;“与经典一起工作”;开放式(fname,r';)";用python?

为什么';";试试看,除了;“与经典一起工作”;开放式(fname,r';)";用python?,python,file,exception-handling,Python,File,Exception Handling,我有一个函数,可以打开一个文件并返回一个打开的文件对象 def read_any(): try: opened = gzip.open(fname, 'r') except IOError: opened = open(fname, 'r') return opened 当我尝试在某个非压缩文件上运行此函数时,除外,不会触发条件,函数会崩溃,并显示以下消息:IOError:不是gzip文件 好的,现在我尝试对语句执行相同的操作: def

我有一个函数,可以打开一个文件并返回一个打开的
文件
对象

def read_any():
    try:
        opened = gzip.open(fname, 'r')
    except IOError:
        opened = open(fname, 'r')
    return opened
当我尝试在某个非压缩文件
上运行此函数时,除
外,不会触发条件,函数会崩溃,并显示以下消息:
IOError:不是gzip文件

好的,现在我尝试对
语句执行相同的操作:

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()
现在,如果我尝试运行相同的文件,该函数将按预期工作。
你能解释一下为什么除
之外的条件没有被触发吗?

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

>>> import gzip
>>> f = gzip.open('some_nongzipped_file', 'r')
您将看到,这不会引发错误。但是,一旦从对象中读取:

>>> f.read()
... (snip)
OSError: Not a gzipped file
,它会引发错误

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

因为在第一个示例中,您只返回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()

IOError不是在创建文件对象时出现的,而是在第一次读取时出现的。我不明白。我假设由
try
包装的任何内容都应该相应地处理
except
。在第二个示例中,您在try except块内调用
.read()
。将两个块中的第一个示例更改为
return opened.read()
,以查看发生了什么。我更改了,
exception
被触发,但我看不到发生了什么:)啊,现在我明白了。有道理。