首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免try-except嵌套

避免try-except嵌套
EN

Stack Overflow用户
提问于 2014-07-03 03:27:05
回答 4查看 247关注 0票数 3

给定一个未知文件类型的文件,我想使用多个处理程序中的一个来打开该文件。如果无法打开文件,则每个处理程序都会引发异常。我想尝试所有的方法,如果都不成功,就抛出一个异常。

我想出的设计是

代码语言:javascript
复制
filename = 'something.something'
try:
    content = open_data_file(filename)
    handle_data_content(content)
except IOError:
    try:
        content = open_sound_file(filename)
        handle_sound_content(content)
    except IOError:
        try:
            content = open_image_file(filename)
            handle_image_content(content)
        except IOError:
            ...

这种级联似乎不是做这件事的正确方法。

有什么建议吗?

EN

回答 4

Stack Overflow用户

发布于 2014-07-03 03:35:56

也许您可以对所有处理程序进行分组,并在for循环中对它们进行计算,如果没有一个处理程序成功,则在结束时引发异常。您还可以保留引发的异常,以从中获取一些信息,如下所示:

代码语言:javascript
复制
filename = 'something.something'
handlers = [(open_data_file, handle_data_context), 
            (open_sound_file, handle_sound_content),
            (open_image_file, handle_image_content)
]
for o, h in handlers:
    try:
        o(filename)
        h(filename)
        break
    except IOError as e:
        pass
else:
    # Raise the exception we got within. Also saves sub-class information.
    raise e
票数 5
EN

Stack Overflow用户

发布于 2014-07-03 06:28:01

检查是完全不可能的吗?

代码语言:javascript
复制
>>> import urllib
>>> from mimetypes import MimeTypes

>>> guess = MimeTypes()
>>> path = urllib.pathname2url(target_file)
>>> opener = guess.guess_type(path)
>>> opener
('audio/ogg', None)

我知道try/excepteafp在Python语言中非常流行,但有时愚蠢的一致性只会干扰手头的任务。

此外,由于您预期的原因,IMO try/except循环可能不一定会中断,而且正如其他人指出的那样,如果您想要在尝试迭代文件打开程序直到成功或失败之前查看实际发生的情况,则需要以一种有意义的方式报告错误。无论哪种方式,都在编写内省代码:深入try/excepts并获得有意义的代码,或者读取文件路径并使用类型检查器,甚至只是拆分文件名以获得扩展名……in the face of ambiguity, refuse the temptation to guess

票数 1
EN

Stack Overflow用户

发布于 2014-07-03 03:53:57

与其他方法一样,我也推荐使用循环,但使用更严格的try/except作用域。

此外,重新引发原始异常总是更好,以便保留有关失败的额外信息,包括回溯。

代码语言:javascript
复制
openers_handlers = [ (open_data_file, handle_data_context) ]

def open_and_handle(filename):
  for i, (opener, handler) in enumerate(openers_handlers):
    try:
        f = opener(filename)
    except IOError:
        if i >= len(openers_handlers) - 1:
            # all failed. re-raise the original exception
            raise
        else:
            # try next
            continue
    else:
        # successfully opened. handle:
        return handler(f)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24539457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档