Câu trả lời:
Có, bạn có thể cài đặt trình xử lý ngắt bằng tín hiệu mô-đun và đợi mãi mãi bằng cách sử dụng luồng .
import signal
import sys
import time
import threading
def signal_handler(signal, frame):
print('You pressed Ctrl+C!')
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
forever = threading.Event()
forever.wait()
while True: continue
vậy. (Theo phong cách while True: pass
đó, dù sao cũng sẽ gọn gàng hơn.) Điều đó sẽ rất lãng phí; thử một cái gì đó như while True: time.sleep(60 * 60 * 24)
(ngủ một ngày trong một thời gian là một con số hoàn toàn tùy ý).
time
(khi bạn nên làm), đừng quên import time
:)
Nếu tất cả những gì bạn muốn là không hiển thị dấu vết, hãy tạo mã của bạn như sau:
## all your app logic here
def main():
## whatever your app does.
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
# do nothing here
pass
(Vâng, tôi biết rằng điều này không trực tiếp trả lời câu hỏi, nhưng không thực sự rõ ràng tại sao cần thử / ngoại trừ khối là điều khó chịu - có thể điều này làm cho nó ít khó chịu hơn đối với OP)
signal.signal( signal.SIGINT, lambda s, f : sys.exit(0))
luôn luôn.
Một cách thay thế để đặt trình xử lý tín hiệu của riêng bạn là sử dụng trình quản lý ngữ cảnh để bắt ngoại lệ và bỏ qua nó:
>>> class CleanExit(object):
... def __enter__(self):
... return self
... def __exit__(self, exc_type, exc_value, exc_tb):
... if exc_type is KeyboardInterrupt:
... return True
... return exc_type is None
...
>>> with CleanExit():
... input() #just to test it
...
>>>
Điều này loại bỏ try
-except
block trong khi vẫn giữ một số đề cập rõ ràng về những gì đang xảy ra.
Điều này cũng cho phép bạn bỏ qua sự gián đoạn chỉ trong một số phần mã của bạn mà không cần phải thiết lập và đặt lại lần nữa các bộ xử lý tín hiệu.
Tôi biết đây là một câu hỏi cũ nhưng tôi đã đến đây trước và sau đó khám phá ra atexit
mô-đun. Tôi chưa biết về hồ sơ theo dõi đa nền tảng của nó hoặc danh sách đầy đủ các cảnh báo, nhưng cho đến nay, đó chính xác là những gì tôi đang tìm kiếm khi cố gắng xử lý sau KeyboardInterrupt
dọn dẹp trên Linux. Chỉ muốn ném vào một cách khác để tiếp cận vấn đề.
Tôi muốn thực hiện dọn dẹp sau khi thoát trong bối cảnh hoạt động của Vải, vì vậy gói mọi thứ trong try
/ except
không phải là một lựa chọn cho tôi. Tôi cảm thấy nhưatexit
có thể phù hợp trong tình huống như vậy, khi mã của bạn không ở cấp cao nhất của luồng kiểm soát.
atexit
rất có khả năng và có thể đọc được ngay từ hộp, ví dụ:
import atexit
def goodbye():
print "You are now leaving the Python sector."
atexit.register(goodbye)
Bạn cũng có thể sử dụng nó như một trình trang trí (kể từ 2.6; ví dụ này là từ tài liệu):
import atexit
@atexit.register
def goodbye():
print "You are now leaving the Python sector."
Nếu bạn chỉ muốn làm cho nó cụ thể KeyboardInterrupt
, câu trả lời của người khác cho câu hỏi này có lẽ tốt hơn.
Nhưng lưu ý rằng atexit
mô-đun chỉ có ~ 70 dòng mã và sẽ không khó để tạo một phiên bản tương tự xử lý các ngoại lệ khác nhau, ví dụ: chuyển các ngoại lệ làm đối số cho các hàm gọi lại. (Hạn chế củaatexit
điều đó sẽ đảm bảo một phiên bản được sửa đổi: hiện tại tôi không thể hình dung được cách để các hàm exit-callback biết về các ngoại lệ; atexit
trình xử lý bắt ngoại lệ, gọi (các) gọi lại của bạn, sau đó tăng lại ngoại lệ đó. Nhưng bạn có thể làm điều này theo cách khác.)
Để biết thêm thông tin, hãy xem:
atexit
Bạn có thể ngăn việc in dấu vết ngăn xếp KeyboardInterrupt
mà không cần try: ... except KeyboardInterrupt: pass
(giải pháp rõ ràng nhất và có thể đề xuất "tốt nhất", nhưng bạn đã biết điều đó và yêu cầu một thứ khác) bằng cách thay thế sys.excepthook
. Cái gì đó như
def custom_excepthook(type, value, traceback):
if type is KeyboardInterrupt:
return # do nothing
else:
sys.__excepthook__(type, value, traceback)
Tôi đã thử các giải pháp được đề xuất bởi mọi người, nhưng tôi phải tự ứng biến mã để thực sự hoạt động. Sau đây là mã ngẫu hứng của tôi:
import signal
import sys
import time
def signal_handler(signal, frame):
print('You pressed Ctrl+C!')
print(signal) # Value is 2 for CTRL + C
print(frame) # Where your execution of program is at moment - the Line Number
sys.exit(0)
#Assign Handler Function
signal.signal(signal.SIGINT, signal_handler)
# Simple Time Loop of 5 Seconds
secondsCount = 5
print('Press Ctrl+C in next '+str(secondsCount))
timeLoopRun = True
while timeLoopRun:
time.sleep(1)
if secondsCount < 1:
timeLoopRun = False
print('Closing in '+ str(secondsCount)+ ' seconds')
secondsCount = secondsCount - 1