gpt4 book ai didi

python - 选择哪一行报异常

转载 作者:行者123 更新时间:2023-12-01 23:50:36 24 4
gpt4 key购买 nike

假设我在 Python 中有一条引发异常的多行代码。

Python 如何决定针对哪一行引发异常?

示例:(注意:我可以在每行之后使用反斜杠 \)

(1
+0/0
+3)

上抛出异常第 3 行 ( ZeroDivisionError 异常(exception),在 +3) 处)。
(1
+
0/0
)

上引发异常第 3 行 .
(0/0
+
1)

上引发异常第 2 行 .

这个问题的灵感来自 this example , 和@Godman pointed out异常不仅仅发生在最后一行(正如我之前所想的那样)。

最佳答案

从根本上说,我不认为我们都在思考正确的路线。这里没有最后一行。解释器在完全接收到表达式时引发异常。根据Python语法:http://docs.python.org/reference/grammar.html , 直到您点击右大括号')',表达式才完全完成。 Joran Beasley 在针对问题本身的评论中对此进行了简要解释。

您可以做 3 件事来判断它的正确性,而无需深入研究语法:-

  • 在python解释器中写下这段代码:

    a=(1+2+0/0+4+5)


  • 这也会引发 ZeroDivionError。
  • 在python解释器中写下这段代码:

    a=(1+2+0/0+4+5 # And, press enter


  • 这会给您带来无效的语法,因为表达式不完整并且无法被解释器解析
    PS:这与问题中提到的代码相同
  • 在python解释器中编写这段代码:

  • a = (1
    +2
    +0/0
    +4
    +5)



    最终,直到您点击右大括号,表达式才会完成。因此,您可以继续在其中添加更多子表达式而不会出现任何异常。因此,从根本上说,解释器并不将这一切都视为行号。它一直等到所有表达式(包括子表达式)都完成。而且,它是一个适合解释器的编程控制流程。

    PS:请原谅我对答案的格式。

    新编辑:-

    @Hayden:我认为通过不深入研究语法可以很容易地解释其中的微妙之处。但是,供您引用,我只是从 URL 复制代码: http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html

    运行步骤:-
    1. 将问题中询问的代码写入 temp.py 文件并保存,然后将 temp 导入另一个文件或解释器中。这将创建 temp.pyc
    2. 现在,将上述 URL 中的完整代码复制并粘贴到 byteCodeDetails.py 中,然后在命令提示符下运行该文件:
    python byteCodeDetails.py temp.pyc。函数 show_file 将在此处调用,并给出以下输出:-

    magic 03f30d0a
    moddate 458c2e50 (Fri Aug 17 23:54:05 2012) code
    argcount 0
    nlocals 0 stacksize 3 flags 0040 code
    640600640200640200151764030017640400175a000064050053 5
    0
    LOAD_CONST 6 (3)
    3 LOAD_CONST 2 (0)
    6 LOAD_CONST 2 (0)
    9 BINARY_DIVIDE
    10 BINARY_ADD
    11 LOAD_CONST 3 (4)
    14 BINARY_ADD
    15 LOAD_CONST 4 (5)
    18 BINARY_ADD
    19 STORE_NAME 0 (a)
    22 LOAD_CONST 5 (None)
    25 RETURN_VALUE
    consts
    1
    2
    0
    4
    5
    None
    3
    names ('a',)
    varnames ()
    freevars ()
    cellvars ()
    filename 'C:\Users\Python\temp1.py'

    name ''
    firstlineno 5
    lnotab



    因此,您可以注意到:-
  • 引用上述链接:
    在反汇编输出中,最左边的数字 (1, 2, 3) 是原始源文件中的行号,接下来的数字 (0, 3, 6, 9, ...) 是指令的字节偏移量.同样,对于您的代码,最左边的数字只有 5,即行号,右边的列代表编译器为您的代码翻译的助记符(由解释器读取),从而指示表达式如何被形成并且它们的形成被编译代码中的行号的值所取代。
  • firSTLineno 指向 5。

  • 现在,只需对 temp.py 文件中的初始代码稍作更改:-

    a = (1
    +2
    +0/0
    +4+
    5)



    现在,再次运行上述 2 个步骤。以下是输出:-

    magic 03f30d0a
    moddate 0f8e2e50 (Sat Aug 18 00:01:43 2012)
    code
    argcount 0
    nlocals 0
    stacksize 3

    flags 0040
    code 640600640200640200151764030017640400175a000064050053
    4
    0 LOAD_CONST 6 (3)
    3 LOAD_CONST 2 (0)
    6 LOAD_CONST 2 (0)
    9 BINARY_DIVIDE
    10 BINARY_ADD
    11 LOAD_CONST 3 (4)
    14 BINARY_ADD

    5 15 LOAD_CONST 4 (5)
    18 BINARY_ADD
    19 STORE_NAME 0 (a)
    22 LOAD_CONST 5 (None)
    25 RETURN_VALUE
    consts
    1
    2
    0
    4
    5
    None
    3
    names ('a',)
    varnames ()
    freevars ()
    cellvars ()
    filename 'C:\Users\Python\temp1.py'
    name ''
    firstlineno 4

    lnotab 0f01



    好吧,现在您可以清楚地看到两件事:-
  • 字节码由下一行所示的 2 行组成,即“代码 640600640200640200151764030017640400175a000064050053”,前缀为“4”和“5”。这表明编译器已经解析了 .py 文件并将 temp.py 中的代码转换为 2 行代码,这些代码将由解释器运行。 注意这里第4行的内容无论表达式是否完整都会被解释器执行
  • 的值firSTLineno 更改为 4 而不是 5

  • 这个冗长讨论的重点是,无论字节码向解释器表明这是一行的开始以及应该为该行执行的相应语句,解释器只运行该行并接下来编写相应的语句给它。

    您问题中的代码将 firSTLineno 显示为 5,这就是您在第 5 行收到错误的原因。希望现在这会有所帮助。

    关于python - 选择哪一行报异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11991756/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com