【问题标题】:How many exceptions are possible when reading a json in Python/django?在 Python/django 中读取 json 时可能出现多少异常?
【发布时间】:2016-05-21 04:09:53
【问题描述】:

我有:

MY_PATH_DIR = 'path/to/my/json/file.json'

try:
    with open(MY_PATH_DIR, 'r') as f:
        MY_PATH_DIR = json.load(f)
except IOError, RuntimeError, ValueError:
    pass
except PermissionDenied:
    pass

我想捕捉所有可能的错误。与

  • IOError - 当文件不存在或有 语法错误(无效的 JSON)。

  • RuntimeError - 无法测试,但我认为从 发生意外错误时的文档

  • ValueError - 我从here 收到以防万一没有返回

  • PermissionDenied - 是特定的 Django 错误

还有其他有意义的例外吗?我不确定OSError 在这里是否有意义。我认为这会更早提出,对吧?

【问题讨论】:

  • 我认为您不会看到 PermissionDenied 错误,因为此代码没有执行任何特定于 django 的操作。并且运行时错误应该只在非常特定的情况下被捕获,当你知道你可以修复程序的状态时。您可以编写一个单元测试来检查各种输入是否存在异常:文件不存在,文件为空,文件包含无效的 json,文件包含非 ascii 字符。此外,您可能不想用 json 加载的结果覆盖您的常量路径。
  • 这是一个叫做“pokemon异常处理”的坏习惯。只捕获你打算处理的异常!
  • 好的,那我只用IOError一个,@BrianSchlenker我测试了你提到的所有案例,他们都被IOError抓住了,谢谢。并且代码在 django 应用程序中,因此 PermissionDenied

标签: python json django exception


【解决方案1】:
import random
import sys


def main():
    """Demonstrate the handling of various kinds of exceptions."""
    # This is like what you are doing in your code.
    exceptions = IOError, RuntimeError, ValueError
    try:
        raise random.choice(exceptions)()
    except exceptions as error:
        print('Currently handling:', repr(error))
    # The following is not much different from Shang Wang's answer.
    try:
        raise random.choice(exceptions)()
    except Exception as error:
        print('Currently handling:', repr(error))
    # However, the following code will sometimes not handle the exception.
    exceptions += SystemExit, KeyboardInterrupt, GeneratorExit
    try:
        raise random.choice(exceptions)()
    except Exception as error:
        print('Currently handling:', repr(error))
    # The code can be slightly altered to take the new errors into account.
    try:
        raise random.choice(exceptions)()
    except BaseException as error:
        print('Currently handling:', repr(error))
    # This does not take into account classes not in the exception hierarchy.
    class Death:
        pass
    try:
        raise Death()
    except BaseException as error:
        print('Currently handling:', repr(error))
    # If your version of Python does not consider raising an exception from an
    # instance of a class not derived from the BaseException class, the way to
    # get around this problem would be with the following code instead.
    try:
        raise Death()
    except:
        error = sys.exc_info()[1]
        print('Currently handling:', repr(error))


if __name__ == '__main__':
    main()

【讨论】:

    【解决方案2】:

    捕获异常的目的是控制程序在发生不好的事情时的行为,但以预期的方式。如果您甚至不确定导致该异常发生的原因,那么捕获它只会吞噬您可能遇到的底层编程错误。

    我不会在单个代码块中添加尽可能多的异常,您应该只添加您关心的内容。更极端地说,每一行代码都会产生某些异常,但出于显而易见的原因,您不能对所有异常都执行try except

    编辑:

    为了正确起见,既然您在任何情况下都提到了I don't want my code to break,您可以简单地这样做:

    try:
        # json.load
    except Exception as e:
        print "Let's just ignore all exceptions, like this one: %s" % str(e)
    

    这将为您提供作为输出发生的异常情况。

    【讨论】:

    • 好吧,我不希望我的代码仅仅因为我正在导入一个 json 文件而中断,所以我关心所有可能导致它中断的情况?
    • 好的,知道了,我只会使用IOError,因为它是我唯一能够打破它的。但是,我不确定 >swallow the underlying programming errors 是什么意思。这个异常只会在我尝试导入这个特定文件时引发,对吧?
    • 如果你用一个你并不真正知道的异常包装了一个代码块,那么你在同一个代码块中有一个错误会导致同样的异常,在这种情况下你总是会捕获异常,认为它正在工作,但从未发现错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    相关资源
    最近更新 更多