2010-11-28 4 views
2

이 코드를 가지고 갈 것입니다 경우 검사합니다. 즉,이 경우 출력은 sth가 될 것입니다. like :파이썬 : 예외 인상이

<function A ...> 

exception_handling_pointer은 어떻게 구현할 수 있습니까?

답변

2

이가 할 수있는 매우 어리석은 것입니다 ... 당신은 단지 관심의 데이트 신청을 희망하고 대부분의 사람들이 할 수없는 것을 말할 것입니다 (THC4k은이의 강력한 증거를 제공합니다 일반 케이 스)하지만 재미 있고 많은 실제 사용 사례에서 완벽하게 수행 할 수 있어야합니다.

단계 1. 프레임을 통해 다시 돌아와야합니다. sys._getframe 또는 inspect.currentframe으로 첫 번째 메시지를 가져옵니다 (아무에게도 말하지 말고, 두 번째 메시지는 첫 번째 메시지의 별칭이됩니다). 그런 다음 f.f_back

단계 2을 사용하여 반복 할 수 있습니다. 각 컴퓨터에는 f.f_lasti 명령이 있습니다. 이것은 프레임에서 실행 된 마지막 명령입니다. 저장해야합니다. 이제 바이트 코드 - f.f_code.co_code을 통해 backwords로 이동하여 으로 점프하는 인수가있는 SETUP_EXCEPT opcode가 f.f_lasti` 이후에 있는지 확인하십시오. 점프 포인트는 예외 처리입니다.

단계 3. 이것은 점점 더 어둡게됩니다. 핵심은 실제 비교 연산이 인수가 10 인 COMPARE_OP 일 것입니다. 내가 본 모든 사례에서 그 다음에 POP_JUMP_IF_FALSE이옵니다. 그러면 다음 except 절 또는 finally 절로 건너 뜁니다. 로드되는 코드 앞에 스택에 예외가로드됩니다. 하나만있는 경우 LOAD_GLOBAL 또는 LOAD_GLOBAL 또는 LOAD_FAST (예외가있는 모듈이 전역 또는 로컬인지 여부에 따라 다름)에 이어 LOAD_ATTR이 오는 직선이됩니다. 일치하는 예외가 여러 개있는 경우에는로드 작업 시퀀스에 BUILD_TUPLE (관용적) 또는 BUILD_LIST (다른 이상한 또는 비 관용적 인 상황)이옵니다.

요점은 LOAD_X 지침을 살펴보고 일치하는 예외와 이름을 비교할 수 있다는 것입니다. 이름이 인 입니다. 이름을 다시 지정하면 당신은 SOL이됩니다.

단계 4. 일치하는 것을 찾았다 고 가정 해 봅시다. 이제 함수 객체가 필요합니다. 이 작업을 수행하는 가장 좋은 방법은 다음과 같습니다 (업데이트 할 수있는 권한이 있음). f.f_codeco_filename 특성을 갖습니다.sys.modules을 통해 반복 할 수 있으며 각 루프에는 __name__ 속성이 있습니다. 당신은 __name__.endswith(co_filename)을 사용해야한다는 것을 기억하면서 두 가지를 비교할 수 있습니다. 일치하는 항목을 찾으면 모듈 함수를 반복하고 해당 f.func_code.co_firstlineno 속성을 프레임 f.f_lineno 속성과 비교할 수 있습니다. 당신이 성냥을 얻을 때, 당신은 당신의 기능이 있습니다. 모듈의 각 클래스의 메서드도 반복해야합니다. 어떤 중첩 된 함수에서 핸들링이 일어날 가능성이 있습니다. 그럴 경우, 나는 현명한 일을 생각할 수 없습니다. (그것은 다른 전체 바이트 코드 해킹이 될 것이고 그 자체가 flakey가 될 것이다)

단계 5. 이익.

이렇게하면 어떻게하는지에 대한 일반적인 아이디어를 얻을 수 있습니다. 당신이 그것을 할 수 없을 것 같은 모든 종류의 코너 케이스가 있지만 어떤 일반적인 사용 케이스에서, 당신은 그것을 뺄 수 있어야합니다. 할 수있는 것에 달려있는 코드를 작성하면 이됩니다. 이것은 일종의 "할 수 있기 때문에 할 수있는 일"입니다.

+0

감사합니다.이 방법을 사용하는 것처럼 보입니다. 그러나 나는 궁금하다. 파이썬 자체가 그런 방식인가? 왜냐하면 그것은 나에게 꽤 비효율적이고 복잡해 보입니다. 나는'SETUP_EXCEPT' op가 실제로 그 정보를 어딘가에 저장한다고 기대한다. 어떻게 든 그것을 읽는 것이 더 쉬울까요? – Albert

+0

@Albert. 이것은 파이썬이하는 방식이 아닙니다. 예를 들어 어셈블리 목록을 보면 파이썬이 어떻게 작동하는지 볼 수 있습니다. 내가 아는 모든 테이블을 저장하지 않습니다. 다양한'* JUMP * '명령과 함께'SETUP_EXCEPT','SETUP_FINALLY','COMPARE_OP'을 사용합니다. 그래서 파이썬 실제로 opcode를 실행합니다. 여기서 우리는 여분의 복잡성이 어디에서 오는 것인지를 조사해야합니다. 파이썬은 내가 아는 한이 항목을 가진 테이블을 저장하지 않습니다. 예를 들어, 컴파일러가 THC4k의 예제에 대한 테이블을 작성하는 방법은 무엇입니까? – aaronasterling

+0

나는 그것에 대해 더 많이 생각할수록,이 정보가 담긴 테이블이 어디에도 없다는 것이 더 긍정적이다. 나는 사람이 어떻게 지어 질 수 있는지를 보지 못한다. 컴파일러는 어떤 예외가 제외되는지 알지 못합니다. 그것들은 범위 정보가있는 심볼 일뿐입니다. – aaronasterling

3

예외를 실제로 발생시키지 않고 예외가 처리되는 위치를 결정할 수 없습니다. 여기에서 쉽게 볼 수 있습니다.

try: 
    raise input('Raise which?') 
except input('Catch which?') as e: 
    pass` 

사용자 입력을 예측하는 데 필요한 모든 기능이 여기에 있습니다. 전체적인 노력은 쓸데없고 파이썬도 지원하지 않습니다. 어쨌든

, 내가

+0

악의적 인 예입니다. 나는 마지막 단락을 두 번째로한다. 그런 일을하는 코드는 깨질 것이다. – delnan

+0

필자는 예외가 발생했을 때 Python에게 점프 할 위치를 알려주는 exception-longjmp-table에 액세스 할 수있는 방법이 있는지를 의미합니다. – Albert

+0

그렇지 않은가? 그리고 각각의 스택 프레임에 모두 저장되어 있고, 그것들이 올라가서 각각에 'except'블록이 있는지 검사한다. 그렇다면,'except' 블록을 가진 첫 번째 스택 프레임을 얻을 수있는 방법이 있습니까? – Albert