我已阅读this on SO之类的问题,我相信我理解使用__getattribute__
的危险。但是,最近我接手了其他人的项目,我需要做一些修改。我认为理解项目的最好方法是跟踪它 - 所以我插入了pdb.set_trace()然后我按下了#34; n \ r \ n" - 但程序没有被执行到下一个行并等待新的输入,但继续执行一直到它的结束。搜索之后,我认为导致问题的是__getattribute__
的误用,但我不知道为什么。我将代码简化为以下内容:
class TestAttribute(object):
"""docstring for TestAttribute"""
def __init__(self, is_testing=False):
super(TestAttribute, self).__init__()
self.is_testing = is_testing
def __getattribute__(self, name):
# print(name)
try:
# the line below will trigger the recursion error
if self.is_testing:
name = name.upper()
return super(TestAttribute, self).__getattribute__(name)
except AttributeError:
return None
except Exception:
# this line is added by me to see the output
import traceback; traceback.print_exc();
return None
def __getitem__(self, name):
return self.__getattribute__(name)
def __setitem__(self, name, val):
return self.__setattr__(name, val)
def __setattr__(self, name, val):
# so this func will be called in __init__ and will
# enter __getattribute__
if self.is_testing:
name = name.lower()
super(TestAttribute, self).__setattr__(name, val)
if __name__ == '__main__':
ttt = TestAttribute()
import pdb; pdb.set_trace()
ttt.k = 1
print('test done')
print('test done again')
print('test done again')
print('test done again')
输出如下:
Traceback (most recent call last):
File "test_getattribute.py", line 10, in __getattribute__
Traceback (most recent call last):
File "test_getattribute.py", line 10, in __getattribute__
if self.is_testing:
File "test_getattribute.py", line 16, in __getattribute__
import traceback; traceback.print_exc();
File "/usr/lib/python2.7/traceback.py", line 232, in print_exc
print_exception(etype, value, tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 125, in print_exception
print_tb(tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 69, in print_tb
line = linecache.getline(filename, lineno, f.f_globals)
File "/home/jgu/repos/.venv/lib/python2.7/linecache.py", line 14, in getline
lines = getlines(filename, module_globals)
File "/home/jgu/repos/.venv/lib/python2.7/linecache.py", line 40, in getlines
return updatecache(filename, module_globals)
RuntimeError: maximum recursion depth exceeded
> /home/jgu/repos/dat_cs/test_getattribute.py(34)<module>()
-> ttt.k = 1
(Pdb) n
Traceback (most recent call last):
File "test_getattribute.py", line 10, in __getattribute__
if self.is_testing:
File "test_getattribute.py", line 7, in __getattribute__
def __getattribute__(self, name):
File "/usr/lib/python2.7/bdb.py", line 50, in trace_dispatch
return self.dispatch_call(frame, arg)
File "/usr/lib/python2.7/bdb.py", line 76, in dispatch_call
if not (self.stop_here(frame) or self.break_anywhere(frame)):
File "/usr/lib/python2.7/bdb.py", line 147, in break_anywhere
return self.canonic(frame.f_code.co_filename) in self.breaks
File "/usr/lib/python2.7/bdb.py", line 29, in canonic
if filename == "<" + filename[1:-1] + ">":
RuntimeError: maximum recursion depth exceeded in cmp
test done
test done again
test done again
test done again
正如你所看到的,我按下了&#34; n \ r \ n&#34;只有并且执行一直持续到程序完成。
还有一个小问题,如果我在没有pdb的情况下运行,我会看到这个输出:
Traceback (most recent call last):
File "test_getattribute.py", line 10, in __getattribute__
Traceback (most recent call last):
File "test_getattribute.py", line 10, in __getattribute__
if self.is_testing:
File "test_getattribute.py", line 16, in __getattribute__
import traceback; traceback.print_exc();
File "/usr/lib/python2.7/traceback.py", line 232, in print_exc
print_exception(etype, value, tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 125, in print_exception
print_tb(tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 69, in print_tb
line = linecache.getline(filename, lineno, f.f_globals)
File "/home/jgu/repos/.venv/lib/python2.7/linecache.py", line 14, in getline
lines = getlines(filename, module_globals)
File "/home/jgu/repos/.venv/lib/python2.7/linecache.py", line 40, in getlines
return updatecache(filename, module_globals)
RuntimeError: maximum recursion depth exceeded
Traceback (most recent call last):
Traceback (most recent call last):
File "test_getattribute.py", line 10, in __getattribute__
if self.is_testing:
File "test_getattribute.py", line 16, in __getattribute__
import traceback; traceback.print_exc();
File "/usr/lib/python2.7/traceback.py", line 232, in print_exc
print_exception(etype, value, tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 125, in print_exception
print_tb(tb, limit, file)
File "/usr/lib/python2.7/traceback.py", line 67, in print_tb
' File "%s", line %d, in %s' % (filename, lineno, name))
RuntimeError: <unprintable RuntimeError object>
test done
test done again
test done again
test done again
所以第二个错误打印不正确,为什么会这样?
编辑:我不是在问为什么会出现递归错误。我相信我很清楚这一点 - 所以请先了解我的问题。感谢
答案 0 :(得分:2)
pdb使用https://github.com/angular/flex-layout#api-overview设置跟踪功能来完成其工作。传播出跟踪功能的任何异常都会禁用它。 RuntimeError在trace函数内部发生,一旦发生就会关闭pdb。