2010-03-01 24 views
17

Khi ngoại lệ xảy ra trong Python, bạn có thể kiểm tra ngăn xếp không? Bạn có thể xác định chiều sâu của nó không? Tôi đã xem xét các mô-đun traceback, nhưng tôi không thể tìm ra cách sử dụng nó.Làm thế nào bạn có thể kiểm tra theo dõi chương trình theo dõi ngăn xếp của một ngoại lệ trong Python?

Mục tiêu của tôi là bắt bất kỳ ngoại lệ nào xảy ra trong quá trình phân tích cú pháp biểu thức eval, mà không bắt ngoại lệ do bất kỳ chức năng nào có thể đã gọi. Đừng bẻ tôi vì sử dụng eval. Đó không phải là quyết định của tôi.

LƯU Ý: Tôi muốn làm điều này theo chương trình, không tương tác.

Trả lời

13

traceback là đủ - và tôi cho rằng tài liệu mô tả nó khá tốt. ví dụ đơn giản:

import sys 
import traceback 

try: 
    eval('a') 
except NameError: 
    traceback.print_exc(file=sys.stdout) 
+2

Tôi không cố in dấu vết. Tôi đang cố kiểm tra nó. Làm thế nào điều này cho tôi biết liệu ngoại lệ xảy ra trong bản thân văn bản eval hay trong một hàm được gọi bởi văn bản được đánh giá? –

+0

Cú pháp Cú pháp sẽ bị ném nếu văn bản 'eval' sai. –

+0

Nhiều loại lỗi khác nhau có thể được ném nếu văn bản eval sai.Tôi đã kết thúc bằng cách sử dụng kiểm tra và xem xét độ sâu của truy nguyên để xem liệu lỗi có phải do đánh giá văn bản gốc hay không hoặc nếu nó nằm trong phần thân của hàm được gọi. –

0

Ngoài câu trả lời AndiDog về inspect, lưu ý rằng pdb cho phép bạn di chuyển lên và xuống ngăn xếp, kiểm tra người dân địa phương và những thứ như vậy. Nguồn trong thư viện chuẩn pdb.py có thể hữu ích cho bạn trong việc học cách làm những việc như vậy.

4

Tôi thích mô-đun truy nguyên.

Bạn có thể nhận đối tượng truy nguyên bằng cách sử dụng sys.exc_info(). Sau đó, bạn có thể sử dụng đối tượng đó để lấy danh sách các mục nhập truy xuất lại bằng danh sách được xử lý trước bằng cách sử dụng traceback.extract_tb(). Sau đó, bạn có thể nhận được một danh sách có thể đọc được bằng traceback.format_list() như sau:

import sys 
import traceback, inspect 

try: 
    f = open("nonExistant file",'r') 
except: 
    (exc_type, exc_value, exc_traceback) = sys.exc_info() 
    #print exception type 
    print exc_type 
    tb_list = traceback.extract_tb(sys.exc_info()[2]) 
    tb_list = traceback.format_list(tb_list) 
    for elt in tb_list: 
     print elt 
     #Do any processing you need here. 

Xem sys Module: http://docs.python.org/library/sys.html

và traceback Module: http://docs.python.org/library/traceback.html

1

Bạn định nghĩa một hàm như vậy():

def raiseErr(): 
    for f in inspect.stack(): print '-', inspect.getframeinfo(f[0]) 

và gọi từ mô-đun của bạn để:

raiseErr() 

Chức năng raiseErr sẽ in thông tin về địa điểm bạn đã gọi.

More phức tạp, bạn có thể làm như vậy:

import inspect, traceback 
A = [inspect.getframeinfo(f[0]) for f in inspect.stack()] 
print "traceback structure fields:", filter(lambda s: s[0] != '_', dir(A[0])) 
print A[0].filename, A[0].lineno 
for f in inspect.stack(): 
    F = inspect.getframeinfo(f[0]) 
    print '-', F.filename, F.lineno, '\t', F.code_context[0].strip() 

Khả năng khác là xác định chức năng này:

def tr(): 
    print '* - '*10, 
    print sys._getframe(1).f_code.co_name 

Và gọi nó là ở nơi bạn muốn theo dõi. Nếu bạn muốn tất cả dấu vết, hãy tạo một trình lặp từ 1 lên trong _getframe(1).