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?

Ohad Dan
sumber
1
Baca jawaban ini: stackoverflow.com/questions/13052991/…
satoru
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).

Raymond Hettinger
sumber
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
4

Lihat dokumen untuk raisepernyataannya . Ini membuat instance MyException.

Jason Fried
sumber
1
Perlu dicatat bahwa sintaks untukraise telah berubah sedikit di Python 3. Bagian yang relevan dengan pertanyaan ini adalah sama ( raise ExceptionTypetetap membuat turunan dari tipe dengan memanggil konstruktornya tanpa argumen).
Blckknght
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()'

Ranjith Udayakumar
sumber