Có cách nào trong Python để nắm bắt sự kiện KeyboardInterrupt
mà không cần đặt tất cả mã trong câu hỏi try
- except
? Tôi muốn xóa sạch nếu không có dấu vết nếu người dùng nhấn ctrl - c.Chụp liên kết bàn phím bằng Python mà không cần thử, ngoại trừ
Trả lời
Có, bạn có thể cài đặt trình xử lý ngắt bằng cách sử dụng signal module.
import signal
import sys
import time
def signal_handler(signal, frame):
print 'You pressed Ctrl+C!'
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print 'Press Ctrl+C'
while True:
time.sleep(1)
Bạn có thể ngăn in dấu vết ngăn xếp cho KeyboardInterrupt
, không có try: ... except KeyboardInterrupt: pass
(giải pháp rõ ràng và tốt nhất "tốt nhất" nhưng bạn đã biết và yêu cầu) bằng cách thay thế sys.excepthook
. Một 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 muốn thoát sạch không dấu vết nếu người dùng nhấn ctrl-c – Alex
bị bắt ==> bị bắt –
Điều này hoàn toàn không đúng. Ngoại lệ KeyboardInterrupt được tạo ra trong một trình xử lý ngắt. Trình xử lý mặc định cho SIGINT tăng KeyboardInterrupt vì vậy nếu bạn không muốn hành vi đó, tất cả những gì bạn phải làm là cung cấp một trình xử lý tín hiệu khác cho SIGINT. Bạn đang đúng trong trường hợp ngoại lệ đó chỉ có thể được xử lý trong một thử/ngoại trừ trong trường hợp này, bạn có thể giữ ngoại lệ từ bao giờ được nêu ra ở nơi đầu tiên. – Matt
Nếu tất cả các bạn muốn là để không hiển thị traceback, làm cho mã của bạn như thế này:
## 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ác câu hỏi, nhưng nó không phải là thực sự rõ ràng lý do tại sao cần một khối try/except có thể bị phản đối - có thể điều này khiến nó ít gây phiền toái cho OP)
Vì lý do nào đó, điều này không phải lúc nào cũng hiệu quả đối với tôi. 'signal.signal (signal.SIGINT, lambda s, f: sys.exit (0))' luôn xảy ra. –
Điều này không phải lúc nào cũng hoạt động với những thứ như pygtk sử dụng chủ đề. Đôi khi^C sẽ chỉ giết luồng hiện tại thay vì toàn bộ quá trình, do đó ngoại lệ sẽ chỉ truyền qua chuỗi đó. –
Có một câu hỏi SO cụ thể về Ctrl + C với pygtk: http://stackoverflow.com/questions/16410852/keyboard-interrupt-with-with-python-gtk – bgporter
Một cách khác để thiết lập trình xử lý tín hiệu của bạn là sử dụng trình quản lý ngữ cảnh để loại trừ 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
...
>>>
Thao tác này sẽ xóa khối try
- except
trong khi vẫn giữ một số đề cập rõ ràng về những gì đang diễn ra.
Điều này cũng cho phép bạn bỏ qua ngắt chỉ trong một số phần mã của bạn mà không phải đặt lại và đặt lại trình xử lý tín hiệu mọi lúc.
tốt đẹp, giải pháp này có vẻ trực tiếp hơn một chút trong việc thể hiện mục đích hơn là đối phó với các tín hiệu. – Seaux
Tôi biết đây là một câu hỏi cũ nhưng tôi đã đến đây trước và sau đó phát hiện ra mô-đun atexit
. Tôi không biết về hồ sơ theo dõi đa nền tảng của nó hoặc một danh sách đầy đủ các cảnh báo nào được nêu ra, nhưng cho đến nay nó là chính xác những gì tôi đang tìm kiếm trong cố gắng để xử lý sau KeyboardInterrupt
dọn dẹp trên Linux. Chỉ muốn ném theo một cách khác để tiếp cận vấn đề.
Tôi muốn làm sạch sau khi xuất cảnh trong bối cảnh hoạt động của Vải, do đó, bao gói mọi thứ trong try
/except
cũng không phải là một tùy 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, nơi mã của bạn không ở mức cao nhất của luồng điều khiển.
atexit
là rất có khả năng và có thể đọc được ra khỏi 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 trang trí (như 2,6; ví dụ này là từ các tài liệu):
import atexit
@atexit.register
def goodbye():
print "You are now leaving the Python sector."
Nếu bạn muốn chỉ định riêng cho 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. Tuy nhiên, lưu ý rằng mô-đun atexit
chỉ là ~ 70 dòng mã và sẽ không khó để tạo ra một phiên bản tương tự xử lý các ngoại lệ khác nhau, ví dụ như truyền ngoại lệ làm đối số cho hàm gọi lại.(Giới hạn của atexit
mà sẽ đảm bảo một phiên bản sửa đổi: hiện tại tôi không thể quan niệm một cách cho các chức năng gọi lại-exit để biết về các trường hợp ngoại lệ; .. -raises ngoại lệ mà Nhưng bạn có thể làm điều này khác nhau)
Để biết thêm thông xem:
- Official documentation on
atexit
- Các Python Module of the Week post, một giới thiệu tốt
- 1. Kích hoạt sự kiện nhấn phím bàn phím mà không cần nhấn phím từ bàn phím
- 2. Ẩn bàn phím ảo hoạt động mà không cần bất kỳ thao tác bàn phím
- 3. python thử trừ 0
- 4. Gửi biểu mẫu bằng phím Enter mà không cần gửi?
- 5. Python - Có thể buộc tăng ngoại lệ bất kể thử/ngoại trừ khối không?
- 6. Thường xuyên lặp lại thử/ngoại trừ trong Python
- 7. Java - Cách thực hiện Thử của Python Trừ Ngoại lệ
- 8. iOS Loại bỏ/Hiển thị bàn phím mà không cần từ chức Đầu tiên Responder
- 9. Đẩy Listview khi bàn phím xuất hiện mà không cần điều chỉnhPan
- 10. Chụp bàn phím toàn cầu trong ứng dụng C#
- 11. Nhiều thử nghiệm trong thử/ngoại trừ khối
- 12. Chụp lần nhấn phím mà không lấy nét
- 13. Nhập bằng bàn phím sử dụng stdio.StandardIO trong python xoắn
- 14. Chạy MySQLDump mà không cần Khóa Bàn
- 15. python nhắn ngoại lệ chụp
- 16. Sử dụng libtool mà không cần sử dụng liên kết
- 17. Nhận đầu vào bàn phím mà không cần trường văn bản/chế độ xem
- 18. Chụp phím "Xóa" bằng jQuery
- 19. Eclipse: Liên kết với phím tắt của trình chỉnh sửa bàn phím?
- 20. Python split() mà không cần tháo delimiter
- 21. Hiển thị bàn phím phần mềm mà không có EditText
- 22. xóa bàn phím khỏi Màn hình mà không cần gọi lại từ chốiFirstResponder
- 23. Phát hiện ẩn bàn phím iPad so với bàn phím bên ngoài có kết nối không?
- 24. Cụm từ thông dụng bao gồm tất cả các ký tự bàn phím ngoại trừ '~' và ','
- 25. Tạo liên kết liên kết đến cửa hàng iTunes mà không cần chuyển hướng?
- 26. Máy chủ SQL: Máy chủ được liên kết mà không cần liên kết máy chủ?
- 27. Nhận một đầu vào từ bàn phím mà không cần 'trở lại' trong C
- 28. Làm thế nào để hiển thị bàn phím mà không cần chạm vào thanh UISearchbar?
- 29. Cách mô phỏng thử cuối cùng hoặc thử ngoại trừ các ngôn ngữ không có chúng
- 30. Chỉ cần số bàn phím mềm?
Lưu ý rằng có một số vấn đề nền tảng cụ thể với mô-đun tín hiệu - không ảnh hưởng đến áp phích này, nhưng "Trên Windows, tín hiệu() chỉ có thể được gọi với SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV hoặc SIGTERM. Một ValueError sẽ được nâng lên trong bất kỳ trường hợp nào khác. " – bgporter
Hoạt động tốt với các chủ đề. Tôi hy vọng bạn không bao giờ làm 'trong khi True: continue', mặc dù. (Trong phong cách đó, 'trong khi True: pass' sẽ là neater, anyway.) Điều đó sẽ rất lãng phí; thử một cái gì đó như 'trong khi True: time.sleep (60 * 60 * 24)' (ngủ cho một ngày tại một thời điểm là một con số hoàn toàn tùy ý). –
Nếu bạn đang sử dụng đề xuất của Chris Morgan về việc sử dụng 'time' (như bạn nên), đừng quên' thời gian nhập' :) – Seaux