2010-12-12 39 views
19

Khi tôi tăng ngoại lệ sở hữu của mình trong thư viện Python, ngăn xếp ngoại lệ hiển thị chính dòng nâng cao làm mục cuối cùng của ngăn xếp. Điều này rõ ràng không phải là một lỗi, là khái niệm đúng, nhưng chỉ tập trung vào một cái gì đó mà không phải là hữu ích để gỡ lỗi khi bạn đang sử dụng mã bên ngoài, ví dụ như một mô-đun.Không hiển thị đường dây nâng cao của Python trong ngăn xếp ngoại lệ

Có cách nào để tránh điều này và buộc Python hiển thị mục ngăn xếp trước đó là mục cuối cùng, như thư viện Python chuẩn.

+7

Đường dây nâng cao bị ẩn khi được tăng từ mã C đã biên dịch (vì không có đường nâng để hiển thị). Các phần Python của các thư viện chuẩn sẽ vẫn hiển thị câu lệnh nâng cao trong một traceback. –

+0

Có lẽ bạn có thể hack 'sys.excepthook' để loại trừ dòng cuối cùng nếu nó là' nâng cao'. Nhưng nói chung là không thể, làm quen với nó. – delnan

+4

Bạn luôn có thể đưa ra một ngoại lệ hữu ích. –

Trả lời

7

Cảnh báo đến hạn: thay đổi hành vi của thông dịch viên thường bị cau mày. Và trong mọi trường hợp, thấy chính xác nơi một lỗi được nêu ra có thể hữu ích trong việc gỡ lỗi, đặc biệt nếu một hàm có thể gây ra lỗi vì nhiều lý do khác nhau.

Nếu bạn sử dụng mô-đun traceback và thay thế sys.excepthook bằng chức năng tùy chỉnh, có thể thực hiện việc này. Nhưng việc thực hiện thay đổi sẽ ảnh hưởng đến hiển thị lỗi cho toàn bộ chương trình, không chỉ mô-đun của bạn, vì vậy có lẽ không được khuyến nghị.

Bạn cũng có thể xem xét việc đặt mã trong thử/ngoại trừ các khối, sau đó sửa đổi lỗi và nâng cấp lại. Nhưng thời gian của bạn có lẽ là tốt hơn dành cho những lỗi không mong muốn không chắc chắn, và viết thông báo lỗi thông tin cho những người có thể phát sinh.

-1

Tôi khuyên bạn không nên sử dụng cơ chế Ngoại lệ để xác thực đối số, như hấp dẫn như vậy. Viết mã với các ngoại lệ như điều kiện giống như nói, "làm hỏng ứng dụng của tôi nếu, với tư cách là nhà phát triển, tôi không nghĩ đến tất cả các điều kiện xấu mà các đối số đã cung cấp của tôi có thể gây ra. Có thể sử dụng ngoại lệ cho những thứ không chỉ ngoài tầm kiểm soát của bạn mà còn dưới sự kiểm soát của một cái gì đó khác như hệ điều hành hoặc phần cứng hoặc ngôn ngữ Python sẽ hợp lý hơn, tôi không biết.Trong thực tế, tôi sử dụng ngoại lệ như bạn yêu cầu một giải pháp cho. nó chỉ là đơn giản để mã thusly:

class MyObject(object): 
    def saveas(self, filename): 
     if not validate_filename(filename): 
      return False 
     ... 

gọi

if not myobject.saveas(filename): report_and_retry() 

Có lẽ không phải là một câu trả lời tuyệt vời, chỉ cần một cái gì đó để suy nghĩ về.

+0

Tôi đã phải upvote này như tôi là tránh càng nhiều trường hợp ngoại lệ càng tốt và chỉ nói với chương trình của tôi để đối phó với nó, bước qua nó, đăng nhập vấn đề, và tiếp tục đi bộ. Tôi đã có nhiều thành công ở đây hơn là ném ngoại lệ ở mọi nơi như mọi người khác ... về cơ bản tôi đang sử dụng print() thay vì tăng – Tcll

+0

Tôi cũng đã nghĩ về mặt khác của điều này, và có khả năng là lý do hầu hết sẽ downvote về điều này (tôi vẫn sẽ không, như bình luận cuối cùng của tôi vẫn đứng), hầu hết các nhà phát triển tốt không chỉ ném ngoại lệ willy nilly cho chỉ là về mọi trường hợp sử dụng sai, chỉ trường hợp đặc biệt xứng đáng một ngoại lệ có được một nâng cao ... được cấp ở trên vẫn có thể xảy ra trong trường hợp cụ thể thậm chí không mã của bạn sẽ bắt. ví dụ: filename là một đối tượng đại diện cho một str. – Tcll

4

bạn có thể tạo móc ngoại lệ của riêng mình trong python. dưới đây là ví dụ về mã mà tôi đang sử dụng.

import sys 
import traceback 

def exceptionHandler(got_exception_type, got_exception, got_traceback): 
    listing = traceback.format_exception(got_exception_type, got_exception, got_traceback) 
    # Removing the listing of statement raise (raise line). 
    del listing[-2] 
    filelist = ["org.python.pydev"] # avoiding the debuger modules. 
    listing = [ item for item in listing if len([f for f in filelist if f in item]) == 0 ] 
    files = [line for line in listing if line.startswith(" File")] 
    if len(files) == 1: 
     # only one file, remove the header. 
     del listing[0] 
    print>>sys.stderr, "".join(listing) 

Và bên dưới là một số dòng mà tôi đã sử dụng trong mã ngoại lệ tùy chỉnh của mình.

sys.excepthook = exceptionHandler 
raise Exception("My Custom error message.") 

Trong trường hợp ngoại lệ, bạn có thể thêm tên tệp hoặc tên mô-đun vào danh sách "tên tệp" nếu bạn muốn bỏ qua bất kỳ tệp không mong muốn nào. Như tôi đã bỏ qua các mô-đun python pydev kể từ khi tôi đang sử dụng trình gỡ lỗi pydev trong nhật thực.

Ở trên được sử dụng trong mô-đun của riêng tôi cho một mục đích cụ thể. bạn có thể sửa đổi và sử dụng nó cho các mô-đun của bạn.

Các vấn đề liên quan