Có sự khác biệt nào giữa “tăng ngoại lệ ()” và “tăng ngoại lệ” mà không có dấu ngoặc đơn không?


99

Định nghĩa một ngoại lệ không tham số:

class MyException(Exception):
    pass

Khi được nâng lên, có bất kỳ sự khác biệt nào giữa:

raise MyException

raise MyException()

Tôi không thể tìm thấy bất kỳ; nó chỉ đơn giản là một cú pháp quá tải?


1
Đọc câu trả lời này: stackoverflow.com/questions/13052991/…
satoru

1
Nói một cách chính xác thì nó không phải cú pháp. Python không thể biết liệu nó sẽ nhận được một lớp hay một cá thể cho đến thời gian chạy.
asmeurer,

Câu trả lời:


114

Câu trả lời ngắn gọn là cả hai raise MyExceptionraise MyException()làm điều tương tự. Biểu mẫu đầu tiên này tự động khởi tạo ngoại lệ của bạn.

Phần có liên quan từ tài liệu cho biết, " raise đánh giá biểu thức đầu tiên là đối tượng ngoại lệ. Nó phải là một lớp con hoặc một thể hiện của BaseException. Nếu nó là một lớp, thể hiện ngoại lệ sẽ nhận được khi cần bằng cách khởi tạo lớp với Không có đối số."

Điều đó nói rằng, mặc dù ngữ nghĩa giống nhau, nhưng dạng thứ nhất nhanh hơn về mặt vi mô, và dạng thứ hai linh hoạt hơn (vì bạn có thể chuyển nó đối số nếu cần).

Kiểu thông thường mà hầu hết mọi người sử dụng trong Python (tức là trong thư viện chuẩn, trong các ứng dụng phổ biến và trong nhiều sách) là sử dụng raise MyExceptionkhi không có đối số. Mọi người chỉ khởi tạo ngoại lệ trực tiếp khi có một số đối số cần được chuyển. Ví dụ: raise KeyError(badkey).


18
Tại sao dạng đầu tiên (không có dấu ngoặc đơn) sẽ nhanh hơn về mặt kính hiển vi?
jamesdlin

15
@jamesdlin Vì mã C để tự động khởi tạo không có chi phí được diễn giải hơn là do bạn tự thực hiện cuộc gọi.
Raymond Hettinger

4

Hãy xem các tài liệu cho raisetuyên bố . Nó tạo ra một phiên bản của MyException.


1
Cần lưu ý rằng cú pháp forraise đã thay đổi một chút trong Python 3. Mặc dù vậy, phần liên quan đến câu hỏi này vẫn giống nhau ( raise ExceptionTypevẫn tạo một thể hiện của kiểu bằng cách gọi hàm tạo của nó mà không có đối số).
Blckknght

0

Đúng, có sự khác biệt giữa ValueErrorValueError()

ValueErrorlà một lớp trong khi ValueError()tạo ra một thể hiện của một lớp. Đây là lý do type(ValueError) is typetype(ValueError()) is ValueError

Mục đích duy nhất raiselà nâng cao ngoại lệ,

khi chúng ta sử dụng ValueError, lớp sẽ được gọi và lần lượt chạy hàm tạo ValueError()

khi chúng ta sử dụng ValueError(), phương thức ValueError()được gọi trực tiếp.

Ghi chú: raise ValueError # shorthand for 'raise ValueError()'

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.