Apakah ada perbedaan antara "memunculkan pengecualian ()" dan "memunculkan pengecualian" tanpa tanda kurung?


99

Mendefinisikan pengecualian tanpa parameter:

class MyException(Exception):
    pass

Saat dinaikkan, apakah ada perbedaan antara:

raise MyException

dan

raise MyException()

Saya tidak dapat menemukannya; apakah itu hanya sintaks yang kelebihan beban?



1
Sebenarnya ini bukan sintaksis. Python tidak dapat mengetahui apakah ia akan mendapatkan kelas atau instance hingga runtime.
asmeurer

Jawaban:


114

Jawaban singkatnya adalah keduanya raise MyExceptiondan raise MyException()melakukan hal yang sama. Formulir pertama ini otomatis membuat pengecualian Anda.

Bagian yang relevan dari dokumen mengatakan, " raise mengevaluasi ekspresi pertama sebagai objek pengecualian. Ini harus berupa subclass atau instance dari BaseException. Jika ini adalah kelas, instance pengecualian akan diperoleh saat diperlukan dengan membuat instance kelas dengan tidak ada argumen. "

Meskipun demikian, meskipun semantiknya sama, bentuk pertama lebih cepat secara mikroskopis, dan bentuk kedua lebih fleksibel (karena Anda dapat menyampaikan argumen jika diperlukan).

Gaya yang biasa digunakan kebanyakan orang dengan Python (yaitu di pustaka standar, di aplikasi populer, dan di banyak buku) akan digunakan raise MyExceptionsaat tidak ada argumen. Orang hanya membuat contoh pengecualian secara langsung jika ada beberapa argumen yang perlu diteruskan. Sebagai contoh: raise KeyError(badkey).


18
Mengapa bentuk pertama (tanpa tanda kurung) lebih cepat secara mikroskopis?
jamesdlin

15
@jamesdlin Karena kode C untuk membuat instance otomatis tidak memiliki overhead yang ditafsirkan daripada berasal dari Anda yang membuat panggilan sendiri.
Raymond Hettinger


0

Ya, ada perbedaan antara ValueErrordanValueError()

ValueErroradalah kelas sambil ValueError()membuat instance kelas. Inilah alasannya type(ValueError) is typedantype(ValueError()) is ValueError

Satu-satunya tujuan raiseadalah untuk meningkatkan pengecualian,

ketika kita menggunakan ValueError, kelas akan dipanggil yang pada gilirannya menjalankan konstruktor ValueError()

ketika kami menggunakan ValueError(), metode ValueError()ini langsung dipanggil.

catatan: raise ValueError # shorthand for 'raise ValueError()'

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.