Apa perbedaan antara raise
dan raise from
dalam Python?
try:
raise ValueError
except Exception as e:
raise IndexError
yang menghasilkan
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError
IndexError
dan
try:
raise ValueError
except Exception as e:
raise IndexError from e
yang menghasilkan
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError from e
IndexError
python
python-3.x
syntax
exception-handling
darkfeline
sumber
sumber
raise IndexError from None
, katakanlah.raise IndexError from False
memunculkanTypeError
, bukanIndexError
. Membuatku bahagia.Jawaban:
Perbedaannya adalah bahwa ketika Anda menggunakan
from
,__cause__
atribut ditetapkan dan pesan menyatakan bahwa pengecualian itu secara langsung disebabkan oleh . Jika Anda menghilangkanfrom
maka tidak__cause__
diatur, tetapi__context__
atribut dapat diatur juga, dan traceback kemudian menunjukkan konteks saat menangani sesuatu yang lain terjadi .Pengaturan
__context__
terjadi jika Anda menggunakanraise
penangan pengecualian; jika Anda digunakan diraise
tempat lain tidak ada__context__
yang diatur.Jika a
__cause__
diatur,__suppress_context__ = True
bendera juga diatur pada pengecualian; ketika__suppress_context__
diatur keTrue
,__context__
diabaikan ketika mencetak traceback.Ketika mengangkat dari penangan pengecualian di mana Anda tidak ingin menampilkan konteks (tidak ingin selama menangani pengecualian terjadi pesan lain), kemudian gunakan
raise ... from None
untuk mengatur__suppress_context__
keTrue
.Dengan kata lain, Python menetapkan konteks pada pengecualian sehingga Anda dapat mengintrospeksi di mana pengecualian muncul, membiarkan Anda melihat apakah pengecualian lain digantikan olehnya. Anda juga dapat menambahkan penyebab ke pengecualian, membuat traceback eksplisit tentang pengecualian lain (menggunakan kata-kata yang berbeda), dan konteksnya diabaikan (tetapi masih dapat diintrospeksi saat debugging). Menggunakan
raise ... from None
memungkinkan Anda menekan konteks yang sedang dicetak.Lihat
raise
dokumentasi pernyataan :Juga lihat dokumentasi Pengecualian bawaan untuk detail tentang konteks dan menyebabkan informasi terlampir pada pengecualian.
sumber
from
dan__cause__
sebagai pengganti implisit__context__
? Apakah ada kasus di mana seseorang akan melampirkan pengecualian yang berbeda dari yang tertangkap olehexcept
?DatabaseError
jika pembukaan basis data gagal. Tetapi jika kegagalan adalah hasil dariIOError
karena file gagal dibuka atauHTTPError
karena URL gagal berfungsi maka itu adalah konteks yang ingin Anda sertakan secara eksplisit, sehingga pengembang yang menggunakan API dapat men-debug mengapa ini. Pada saat itu Anda gunakanraise DatabaseError from original_exception
.IOError
atauHTTPError
kepada konsumen mereka , maka mereka harus menggunakannyaraise NewException from databaseexception.__cause__
, sekarang menggunakan pengecualian berbeda dariDatabaseException
yang baru saja mereka tangkap.foo
, dan ingin mengajukan pengecualian barubar
? Kemudian Anda dapat menggunakanraise bar from foo
dan memiliki status Python yangfoo
secara langsung disebabkanbar
. Jika Anda tidak menggunakanfrom foo
, maka Python akan tetap mencetak keduanya, tetapi menyatakan bahwa selama penangananfoo
,bar
dibesarkan , pesan berbeda, dimaksudkan untuk menandai kemungkinan bug dalam penanganan kesalahan.