Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python错误后无法交互访问本地变量_Python_Interactive - Fatal编程技术网

Python错误后无法交互访问本地变量

Python错误后无法交互访问本地变量,python,interactive,Python,Interactive,如果在交互(-i)模式下运行python脚本,为了帮助调试,如何在发生错误时访问堆栈帧 剧本 # pytest.py def foo(x): assert False foo(24601) 命令会话 D:\>python.exe -i pytest.py Traceback (most recent call last): File "pytest.py", line 4, in <module> foo(3) File "pytest.py", l

如果在交互(
-i
)模式下运行python脚本,为了帮助调试,如何在发生错误时访问堆栈帧

剧本

# pytest.py
def foo(x):
    assert False

foo(24601)
命令会话

D:\>python.exe -i pytest.py
Traceback (most recent call last):
  File "pytest.py", line 4, in <module>
    foo(3)
  File "pytest.py", line 2, in foo
    assert False
AssertionError
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
D:\>python.exe-i pytest.py
回溯(最近一次呼叫最后一次):
文件“pytest.py”,第4行,在
傅(3)
文件“pytest.py”,第2行,在foo中
断言错误
断言错误
>>>x
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
名称错误:未定义名称“x”

在这种情况下,如果断言失败,如何访问x的值?

使用python调试器-


(您不需要-i标志)

使用python调试器-

(您不需要它-i标志)

Python调试器的答案听起来不错。但是,如果你想尝试“其他东西”。 我找到了这个东西,它看起来就像你在寻找的答案。您可以使用回溯模块构建一个函数,在发生错误时逐帧打印局部变量。从那里,我想你可以从日志中提取数据

如链接示例中所述:

import sys, traceback

def print_exc_plus():
    """
    Print the usual traceback information, followed by a listing of all the
    local variables in each frame.
    """
    tb = sys.exc_info()[2]
    while 1:
        if not tb.tb_next:
            break
        tb = tb.tb_next
    stack = []
    f = tb.tb_frame
    while f:
        stack.append(f)
        f = f.f_back
    stack.reverse()
    traceback.print_exc()
    print "Locals by frame, innermost last"
    for frame in stack:
        print
        print "Frame %s in %s at line %s" % (frame.f_code.co_name,
                                             frame.f_code.co_filename,
                                             frame.f_lineno)
        for key, value in frame.f_locals.items():
            print "\t%20s = " % key,
            #We have to be careful not to cause a new error in our error
            #printer! Calling str() on an unknown object could cause an
            #error we don't want.
            try:
                print value
            except:
                print "<ERROR WHILE PRINTING VALUE>"


if __name__ == '__main__':
    #A simplistic demonstration of the kind of problem this approach can help
    #with. Basically, we have a simple function which manipulates all the
    #strings in a list. The function doesn't do any error checking, so when
    #we pass a list which contains something other than strings, we get an
    #error. Figuring out what bad data caused the error is easier with our
    #new function.

    data = ["1", "2", 3, "4"] #Typo: We 'forget' the quotes on data[2]
    def pad4(seq):
        """
        Pad each string in seq with zeros, to four places. Note there
        is no reason to actually write this function, Python already
        does this sort of thing much better.
        Just an example.
        """
        return_value = []
        for thing in seq:
            return_value.append("0" * (4 - len(thing)) + thing)
        return return_value

    #First, show the information we get from a normal traceback.print_exc().
    try:
        pad4(data)
    except:
        traceback.print_exc()
    print
    print "----------------"
    print

    #Now with our new function. Note how easy it is to see the bad data that
    #caused the problem. The variable 'thing' has the value 3, so we know
    #that the TypeError we got was because of that. A quick look at the
    #value for 'data' shows us we simply forgot the quotes on that item.
    try:
        pad4(data)
    except:
        print_exc_plus()
导入系统,回溯
def print_exc_plus():
"""
打印通常的回溯信息,然后列出所有
每个帧中的局部变量。
"""
tb=sys.exc_info()[2]
而1:
如果不是tb.tb\U下一步:
打破
tb=tb.tb\u下一步
堆栈=[]
f=tb.tb\u帧
而f:
stack.append(f)
f=f.f_后
stack.reverse()
traceback.print_exc()
打印“本地帧,最里面的最后一帧”
对于堆栈中的帧:
打印
打印“第%s行%s中的第%s帧”%(Frame.f_code.co_name,
frame.f_code.co_文件名,
框架(f_线号)
对于键,frame.f_locals.items()中的值:
打印“\t%20s=“%key,
#我们必须小心,不要在我们的错误中造成新的错误
#打印机!对未知对象调用str()可能会导致
#我们不想要的错误。
尝试:
打印值
除:
打印“”
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#这种方法能帮助解决的问题过于简单化
#有。基本上,我们有一个简单的函数来处理所有
#列表中的字符串。该函数不执行任何错误检查,因此
#当我们传递一个包含字符串以外的内容的列表时,我们得到一个
#错误。使用我们的
#新功能。
数据=[“1”、“2”、“3”、“4”]#打字错误:我们“忘记”了数据上的引号[2]
def pad4(序号):
"""
在seq中的每个字符串上加上零,四个位置。注意这里
没有理由实际编写这个函数,Python已经开始了
这类事情做得更好。
只是一个例子。
"""
返回值=[]
对于以下内容:
return_value.append(“0”*(4-len(thing))+thing)
返回值
#首先,显示我们从正常回溯中获得的信息。
尝试:
pad4(数据)
除:
traceback.print_exc()
打印
打印“--------------------”
打印
#现在使用我们的新功能。请注意,查看错误数据是多么容易
#造成问题的原因。变量thing的值是3,所以我们知道
#我们的打字错误就是因为这个。快速查看
#“数据”的值显示我们只是忘记了该项目的报价。
尝试:
pad4(数据)
除:
打印exc exc plus()
执行代码后,我得到了包含局部变量及其值的输出

TypeError: object of type 'int' has no len()
                __name__ =  __main__
                    data =  ['1', '2', 3, '4']
                 __doc__ =  None
          print_exc_plus =  <function print_exc_plus at 0x7ffb8ee86668>

Frame pad4 in /home/robert.sawicki/PycharmProjects/python_challenge/test.py at line 55
                   thing =  3
            return_value =  ['0001', '0002']
                     seq =  ['1', '2', 3, '4']
TypeError:int类型的对象没有len()
__名称\uuuuu=\uuuuuu main__
数据=['1','2',3',4']
__doc_uu;=无
打印exc plus=
第55行的Frame pad4 in/home/robert.sawicki/PycharmProjects/python_challenge/test.py
事物=3
返回值=['0001','0002']
seq=['1','2',3',4']

Python调试器的答案听起来不错。但是,如果你想尝试“其他东西”。 我找到了这个东西,它看起来就像你在寻找的答案。您可以使用回溯模块构建一个函数,在发生错误时逐帧打印局部变量。从那里,我想你可以从日志中提取数据

如链接示例中所述:

import sys, traceback

def print_exc_plus():
    """
    Print the usual traceback information, followed by a listing of all the
    local variables in each frame.
    """
    tb = sys.exc_info()[2]
    while 1:
        if not tb.tb_next:
            break
        tb = tb.tb_next
    stack = []
    f = tb.tb_frame
    while f:
        stack.append(f)
        f = f.f_back
    stack.reverse()
    traceback.print_exc()
    print "Locals by frame, innermost last"
    for frame in stack:
        print
        print "Frame %s in %s at line %s" % (frame.f_code.co_name,
                                             frame.f_code.co_filename,
                                             frame.f_lineno)
        for key, value in frame.f_locals.items():
            print "\t%20s = " % key,
            #We have to be careful not to cause a new error in our error
            #printer! Calling str() on an unknown object could cause an
            #error we don't want.
            try:
                print value
            except:
                print "<ERROR WHILE PRINTING VALUE>"


if __name__ == '__main__':
    #A simplistic demonstration of the kind of problem this approach can help
    #with. Basically, we have a simple function which manipulates all the
    #strings in a list. The function doesn't do any error checking, so when
    #we pass a list which contains something other than strings, we get an
    #error. Figuring out what bad data caused the error is easier with our
    #new function.

    data = ["1", "2", 3, "4"] #Typo: We 'forget' the quotes on data[2]
    def pad4(seq):
        """
        Pad each string in seq with zeros, to four places. Note there
        is no reason to actually write this function, Python already
        does this sort of thing much better.
        Just an example.
        """
        return_value = []
        for thing in seq:
            return_value.append("0" * (4 - len(thing)) + thing)
        return return_value

    #First, show the information we get from a normal traceback.print_exc().
    try:
        pad4(data)
    except:
        traceback.print_exc()
    print
    print "----------------"
    print

    #Now with our new function. Note how easy it is to see the bad data that
    #caused the problem. The variable 'thing' has the value 3, so we know
    #that the TypeError we got was because of that. A quick look at the
    #value for 'data' shows us we simply forgot the quotes on that item.
    try:
        pad4(data)
    except:
        print_exc_plus()
导入系统,回溯
def print_exc_plus():
"""
打印通常的回溯信息,然后列出所有
每个帧中的局部变量。
"""
tb=sys.exc_info()[2]
而1:
如果不是tb.tb\U下一步:
打破
tb=tb.tb\u下一步
堆栈=[]
f=tb.tb\u帧
而f:
stack.append(f)
f=f.f_后
stack.reverse()
traceback.print_exc()
打印“本地帧,最里面的最后一帧”
对于堆栈中的帧:
打印
打印“第%s行%s中的第%s帧”%(Frame.f_code.co_name,
frame.f_code.co_文件名,
框架(f_线号)
对于键,frame.f_locals.items()中的值:
打印“\t%20s=“%key,
#我们必须小心,不要在我们的错误中造成新的错误
#打印机!对未知对象调用str()可能会导致
#我们不想要的错误。
尝试:
打印值
除:
打印“”
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#这种方法能帮助解决的问题过于简单化
#有。基本上,我们有一个简单的函数来处理所有
#列表中的字符串。该函数不执行任何错误检查,因此
#当我们传递一个包含字符串以外的内容的列表时,我们得到一个
bruno@bigb:~/Work/playground$ cat pytest.py
# pytest.py
def foo(x):
    assert False

def main():
    print foo(24601)


if __name__ == "__main__":
    main()

bruno@bigb:~/Work/playground$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
Type "help", "copyright", "credits" or "license" for more information.
>>> import pytest
>>> import pdb
>>> pdb.runcall(pytest.main)
> /home/bruno/Work/playground/pytest.py(6)main()
-> print foo(24601)
(Pdb) s
--Call--
> /home/bruno/Work/playground/pytest.py(2)foo()
-> def foo(x):
(Pdb) l
  1     # pytest.py
  2  -> def foo(x):
  3         assert False
  4     
  5     def main():
  6         print foo(24601)
  7     
  8     
  9     if __name__ == "__main__":
 10         main()
[EOF]
(Pdb) n
> /home/bruno/Work/playground/pytest.py(3)foo()
-> assert False
(Pdb) !x
24601
(Pdb) c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pdb.py", line 1248, in runcall
    return Pdb().runcall(*args, **kwds)
  File "/usr/lib/python2.7/bdb.py", line 436, in runcall
    res = func(*args, **kwds)
  File "pytest.py", line 6, in main
    print foo(24601)
  File "pytest.py", line 3, in foo
    assert False
AssertionError
>>>