Locating the line number where an exception occurs

2020-02-10 05:12发布

I have a code similar to this:

try:
  if x:
      statement1
      statement2
      statement3
  elif y:
      statement4
      statement5
      statement6
  else:
      raise

except:
      statement7

Here, I am sure that the exception occurs in If x: block, but I would like to know in which statement of If x: block the exception occurs. Is there a way to get the line number where the exception occurs?

Regards,

10条回答
干净又极端
2楼-- · 2020-02-10 05:40

I believe the several answers here recommending you manage your try/except blocks more tightly are the answer you're looking for. That's a style thing, not a library thing.

However, at times we find ourselves in a situation where it's not a style thing, and you really do need the line number to do some other programattic action. If that's what you're asking, you should consider the traceback module. You can extract all the information you need about the most recent exception. The tb_lineno function will return the line number causing the exception.

>>> import traceback
>>> dir(traceback)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_format_final_exc_line', '_print', '_some_str', 'extract_stack', 'extract_tb', 'format_exc', 'format_exception', 'format_exception_only', 'format_list', 'format_stack', 'format_tb', 'linecache', 'print_exc', 'print_exception', 'print_last', 'print_list', 'print_stack', 'print_tb', 'sys', 'tb_lineno', 'types']
>>> help(traceback.tb_lineno)
Help on function tb_lineno in module traceback:

tb_lineno(tb)
Calculate correct line number of traceback given in tb.
Obsolete in 2.3

Newer versions of the traceback plumbing fix the issue prior to 2.3, allowing the code below to work as it was intended: (this is the "right way")

import traceback
import sys

try:
    raise Exception("foo")
except:
    for frame in traceback.extract_tb(sys.exc_info()[2]):
        fname,lineno,fn,text = frame
        print "Error in %s on line %d" % (fname, lineno)
查看更多
啃猪蹄的小仙女
3楼-- · 2020-02-10 05:40

You should run your program in a debugger, such as pdb. This will allow you to run your code normally, and then examine the environment when something unexpected like this occurs.

Given a script named 'main.py', run it like this:

python -m pdb main.py

Then, when your program starts, it will start in the debugger. Type c to continue until the next breakpoint (or crash). Then, you can examine the environment by doing things like print spam.eggs. You can also set breakpoints by doing pdb.set_trace() (I commonly do import pdb; pdb.set_trace()).

Additionally, what do you mean that it is "okay" for 'statement 3' to raise the exception? Are you expecting the exception? If so, it might be better to write a try/except block around this statement, so that the program can continue.

查看更多
该账号已被封号
4楼-- · 2020-02-10 05:41

I've done the following before:

try:
    doing = "statement1"
    statement1
    doing = "statement2"
    statement2
    doing = "statement3"
    statement3
    doing = "statement4"
    statement4

 except:
    print "exception occurred doing ", doing

The advantage over printing checkpoints is there's no log output unless there actually is an exception.

查看更多
够拽才男人
5楼-- · 2020-02-10 05:41

we can get the line number by splitting the string state of the traceback.format_exc(). please try running the following code..

import traceback

try:
    a = "str"
    b = 10

    c = a + b
except Exception as e:
    err_lineno = str(traceback.format_exc()).split(",")[1]
    print(err_lineno)

this will produce the following output

line 7
查看更多
登录 后发表回答