this on SO과 같은 질문을 읽었으며 __getattribute__
을 사용하는 위험을 이해하고 있습니다. 그러나 최근에는 다른 사람들의 프로젝트를 인수했고 수정해야합니다. 나는 프로젝트를 이해하는 가장 좋은 방법은 그것을 추적하는 것이라고 생각한다. 그래서 pdb.set_trace()를 삽입하고 "n \ r \ n"을 눌렀다. 그러나 프로그램은 다음 줄로 실행되지 않고 새로운 것을 기다린다. 대신 입력을 끝까지 계속 실행하십시오. 검색을 한 후에는 문제의 원인이되는 __getattribute__
의 오용이라고 생각하지만 이유는 알 수 없습니다. 아래예를 들어 파이썬 코드 스 니펫을 사용하여 __getattribute__ 및 pdb.set_trace()를 이해하십시오
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
, 나는 단지 "N \ r \ n을"누를 실행 프로그램에 대한 모든 방법을 계속 나는 다음에 코드를 단순화 끝내라.
그리고 또 다른 작은 문제는 내가 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
이 왜
입니다?편집 : 왜 재귀 오류가 발생하는지 묻지 않습니다. 나는 그 부분에 내가 분명하다고 믿는다. 그래서 제 질문을 먼저 이해해주십시오. 감사합니다
'if self.is_testing' - 글쎄, 어떻게'self.is_testing' 값을 찾았습니까? 당신은'__getattribute__'를 호출합니다. '__getattribute__'를 실행하려면, 먼저'self.is_testing'를 체크하십시오. 'self.is_testing'의 가치를 어떻게 찾으십니까? 당신은'__getattribute__'를 호출합니다 ... – user2357112
왜 재귀 오류가 발생하는지 묻지 않습니다. 나는 그 부분에서 내가 분명하다고 생각한다. –