Tôi đang viết một tiện ích dòng lệnh bằng Python, vì nó là mã sản xuất, nên có thể tắt sạch mà không đổ nhiều thứ (mã lỗi, dấu vết ngăn xếp, v.v.) ra màn hình. Điều này có nghĩa là tôi cần phải bắt các ngắt bàn phím.
Tôi đã thử sử dụng cả hai khối try catch như:
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print 'Interrupted'
sys.exit(0)
và tự bắt tín hiệu (như trong bài đăng này ):
import signal
import sys
def sigint_handler(signal, frame):
print 'Interrupted'
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
Cả hai phương pháp dường như hoạt động khá tốt trong quá trình hoạt động bình thường. Tuy nhiên, nếu gián đoạn xảy ra trong khi mã dọn dẹp ở cuối ứng dụng, Python dường như luôn in thứ gì đó ra màn hình. Bắt được gián đoạn cho
^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored
trong khi xử lý tín hiệu cho
^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored
hoặc là
^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored
Những lỗi này không chỉ xấu mà còn không hữu ích lắm (đặc biệt đối với người dùng cuối không có mã nguồn)!
Mã dọn dẹp cho ứng dụng này khá lớn, vì vậy có nhiều khả năng vấn đề này sẽ do người dùng thực gây ra. Có cách nào để bắt hoặc chặn đầu ra này không, hay nó chỉ là thứ mà tôi sẽ phải giải quyết?
sys.stdout
/sys.stderr
? Nhưsys.stderr = open(os.devnull, 'w')
thế nào?. Nếu bạn thực sự không quan tâm đến kết quả cuối cùng thì đây có vẻ như là giải pháp hiển nhiên.