Sự khác biệt giữa ngoại trừ: và ngoại trừ Ngoại lệ như e: trong Python


140

Cả hai đoạn mã sau đây đều làm điều tương tự. Họ bắt mọi ngoại lệ và thực thi mã trong except:khối

Đoạn 1 -

try:
    #some code that may throw an exception
except:
    #exception handling code

Đoạn 2 -

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code

Chính xác sự khác biệt trong cả hai cấu trúc là gì?


7
@ user2725093 đó không phải là câu hỏi tương tự. Người bạn liên kết để hỏi sự khác biệt giữa except Exception, e:except Exception as e:. Câu hỏi này hỏi sự khác biệt giữa except:except Exception as e:.
Dennis

Câu trả lời:


154

Trong lần thứ hai, bạn có thể truy cập các thuộc tính của đối tượng ngoại lệ:

>>> def catch():
...     try:
...         asd()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)

Nhưng nó không bắt BaseExceptionhoặc các ngoại lệ hệ thống thoát SystemExit, KeyboardInterruptGeneratorExit:

>>> def catch():
...     try:
...         raise BaseException()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch
BaseException

Mà trần trừ:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 

Xem phần Ngoại lệ tích hợp của tài liệu và phần Lỗi và ngoại lệ của hướng dẫn để biết thêm thông tin.


21
Chà, không có phép thuật ở đây. Exceptioncó nguồn gốc từ BaseException, đó là lý do tại sao except Exceptionkhông bắt BaseException. Nếu bạn viết except BaseException, nó cũng sẽ bị bắt. Bare exceptchỉ bắt tất cả mọi thứ.
fjarri

2
Tôi nên chỉ ra rằng một khoảng trống exceptphải tồn tại trong một loạt các exceptkhối, trong khi bạn sẽ không gặp lỗi nếu bạn đặt except Exceptiontrước các exceptkhối khác : chúng sẽ bị bỏ qua một cách im lặng (nếu chúng xử lý các Exceptionlớp con). Một cái gì đó để coi chừng.
Vanessa Phipps

@MatthewPhipps Đó là loại quan điểm, phải không? như các câu lệnh tình huống hoặc các khối if-if khác, thực thi nhảy đến điều kiện đầu tiên khớp với ...
Basic

1
@Basic Chỉ cần chỉ ra một sự khác biệt khác giữa trần exceptexcept Exception. "Một cái gì đó để ý" bây giờ trông hơi kỳ lạ, nhưng tại thời điểm đó tôi mong đợi Python chọn exceptkhối cụ thể nhất , bất kể nó ở đâu, và hơi thất vọng khi tìm ra cách khác.
Vanessa Phipps

Cũng cần lưu ý rằng hình thức thứ hai chỉ nên được sử dụng nếu bạn không quan tâm đến ngoại lệ là gì hoặc muốn xử lý nó theo cách có ý nghĩa.
Josh J

51
except:

chấp nhận tất cả các ngoại lệ, trong khi

except Exception as e:

chỉ chấp nhận trường hợp ngoại lệ mà bạn đang có nghĩa là để nắm bắt.

Đây là một ví dụ về một thứ mà bạn không định bắt:

>>> try:
...     input()
... except:
...     pass
... 
>>> try:
...     input()
... except Exception as e:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

Người đầu tiên im lặng KeyboardInterrupt!

Dưới đây là danh sách nhanh:

issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False


issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False


issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False

Nếu bạn muốn bắt bất kỳ ai trong số đó, tốt nhất nên làm

except BaseException:

để chỉ ra rằng bạn biết những gì bạn đang làm.


Tất cả các trường hợp ngoại lệ bắt nguồn từ BaseExceptionvà những trường hợp bạn định bắt hàng ngày (những thứ sẽ được ném cho lập trình viên) cũng thừa hưởng từ Exception.


except(Exception)không bao giờ bắt KeyboardInterruptlỗi. as ekhông có gì để làm với nó
pandita

2
Tôi không bao giờ nói rằng nó đã làm. Tôi đã không một lần đề cập đến as e, bởi vì tôi cho rằng nó rõ ràng những gì nó làm.
Veedrac

2
Có trường hợp một người sẽ bắt BaseException VÀ biết họ đang làm gì không?
Davos

2
@Davos Vâng, bạn có thể thích nó khi thực hiện ghi nhật ký tạm thời hoặc nếu bạn đang cung cấp bảng điều khiển cho người dùng mà bạn không muốn có ngoại lệ như SystemExithoặc KeyboardInterruptthoát khỏi. Không phải là một trường hợp phổ biến, nhưng nó xảy ra.
Veedrac

14

Có một số khác biệt với một số trường hợp ngoại lệ, ví dụ KeyboardInterrupt.

Đọc PEP8 :

Một mệnh đề ngoại trừ: sẽ bắt các ngoại lệ SystemExit và KeyboardInterrupt, khiến cho việc gián đoạn chương trình với Control-C trở nên khó khăn hơn và có thể ngụy trang các vấn đề khác. Nếu bạn muốn bắt tất cả các ngoại lệ báo hiệu lỗi chương trình, hãy sử dụng ngoại trừ Ngoại lệ: (ngoại trừ tương đương với ngoại trừ BaseException :).


3

Sử dụng biểu mẫu thứ hai cung cấp cho bạn một biến (được đặt tên dựa trên asmệnh đề, trong ví dụ của bạn e) trong exceptphạm vi khối với đối tượng ngoại lệ được liên kết với nó để bạn có thể sử dụng thông tin trong ngoại lệ (loại, thông báo, dấu vết ngăn xếp, v.v.) xử lý ngoại lệ trong một trang viên được thiết kế đặc biệt hơn.


1

Một cách khác để xem xét điều này. Kiểm tra các chi tiết của ngoại lệ:

In [49]: try: 
    ...:     open('file.DNE.txt') 
    ...: except Exception as  e: 
    ...:     print(dir(e)) 
    ...:                                                                                                                                    
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'characters_written', 'errno', 'filename', 'filename2', 'strerror', 'with_traceback']

Có rất nhiều "thứ" để truy cập bằng cú pháp 'as e'.

Mã này chỉ nhằm mục đích hiển thị chi tiết của trường hợp này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.