2017-11-08 1 views
1

exec을 통해 몇 가지 기능을 만들고 있습니다. 오류 일 수 있습니다. 그러나 Python 오류가 발생하면 오류가 발생한 행은 표시되지 않습니다. 사용 예를 들어파일 "<string>"라인 미리보기로 추적하십시오.

:

Traceback (most recent call last): 
    File "...", line 10, in <module> 
    fn() 
    File "<string>", line 2, in fn 
Exception 

것은 우리가하지만, 평가 후면 사용하지 않는 경우 :

fn_str = '''\ 
def fn(): 
    raise Exception() 
''' 

globs = {} 
exec(fn_str, globs) 
fn = globs['fn'] 

fn() 

은 우리에게 출력을 제공합니다. 나는 __traceback__를 사용하여 살펴본 결과

def fn(): 
    raise Exception() 

fn() 
Traceback (most recent call last): 
    File "...", line 4, in <module> 
    fn() 
    File "...", line 2, in fn 
    raise Exception() 
Exception 

는, 그러나 나는 '파일에서 역 추적에 추가 할 수있는 방법을 찾을 수 없습니다 : 그런 다음 우리는 프로그램에 오류가 발생한 라인을 얻을 ' 선. 그래서 내가 할 수있는 최선이었다이 :

fn_str = '''\ 
def fn(): 
    try: 
     raise Exception() 
    except BaseException as e: 
     tb = e.__traceback__ 
     if 1 <= tb.tb_lineno <= len(fn_lines): 
      e.args = ((e.args[0] if e.args else '') + ' - ' + fn_lines[tb.tb_lineno - 1].strip(),) 
     raise 
''' 

globs = {'fn_lines': fn_str.split('\n')} 
exec(fn_str, globs) 
fn = globs['fn'] 

fn() 
Traceback (most recent call last): 
    File "...", line 16, in <module> 
    fn() 
    File "<string>", line 3, in fn 
Exception: - raise Exception() 

- raise Exception()가 나오는 곳 eval 통화를 다른 코드는,이 혼란 될 경우이 가장 큰 문제입니다.


오류 코드에 오류 코드를 제공하는 방법이 있습니까?

답변

2

인터프리터가 어떤 이유에서 건 의 소스 코드를 찾을 수없는 경우 이런 일이 발생합니다. 이것은 당신이 fn의 코드 객체의 파일 이름이 <string>

File "<string>", line 2, in fn 
로 설정되어 있음을 알 수 역 추적에, 더 구체적으로 등 내장 모듈, 컴파일 된 파일, exec 문자열의 경우입니다

<string>은 유효한 파일 이름이 아니기 때문에 소스 코드에 대한 참조가 손실됩니다.

하나의 옵션은 컴파일 된 코드를 파일 이름을 설정 실행 fn_str를 컴파일하고 마지막으로 함수를 호출, 임시 파일을 만들고 거기에 fn_str을 작성하는 것입니다. 소스 라인은 역 추적 - 인쇄 시설에서

from tempfile import NamedTemporaryFile 
import traceback 

with NamedTemporaryFile('w') as temp: 
    code = compile(fn_str, temp.name, 'exec') 
    print(fn_str, file=temp, flush=True) 
    globs = {} 
    exec(code, globs) 
    fn = globs['fn'] 
    try: 
     fn() 
    except: 
     traceback.print_exc() 

인쇄

Traceback (most recent call last): 
    File "test.py", line 16, in <module> 
    fn() 
    File "/tmp/tmp9q2bogm6", line 2, in fn 
    raise Exception() 
Exception 

를 캐시 전까지는 우리가 이미 "진짜"를 만들 수 있기 때문에 당신이 살아 을 파일을 유지해야합니다 파일, 우리는 runpy.run_path에 컴파일과 코드의 실행을 위임 할 수 있습니다 : 이것은 영리

from tempfile import NamedTemporaryFile 
import runpy, traceback 

with NamedTemporaryFile('w') as temp: 
    print(fn_str, file=temp, flush=True) 
    fn = runpy.run_path(temp.name)['fn'] 
    try: 
     fn() 
    except: 
     traceback.print_exc() 
+0

, 감사합니다. 'NamedTemporaryFile'을 사용할 때 몇 가지 Windows 사용 권한 오류가 발생했습니다. 그러나 파일을 만드는 데 다른 방법을 사용하면 효과적이었습니다. – Peilonrayz