Saat Anda hanya ingin mencoba-kecuali tanpa menangani pengecualian, bagaimana Anda melakukannya dengan Python?
Apakah mengikuti cara yang benar untuk melakukannya?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Saat Anda hanya ingin mencoba-kecuali tanpa menangani pengecualian, bagaimana Anda melakukannya dengan Python?
Apakah mengikuti cara yang benar untuk melakukannya?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Jawaban:
try:
doSomething()
except:
pass
atau
try:
doSomething()
except Exception:
pass
Perbedaannya adalah bahwa yang pertama juga akan menangkap KeyboardInterrupt
, SystemExit
dan hal-hal seperti itu, yang berasal langsung dari exceptions.BaseException
, bukan exceptions.Exception
.
Lihat dokumentasi untuk detail:
try: shuti.rmtree(...) except: pass
akan secara kasar menekan kesalahan (bahkan jika Anda salah mengeja shutil
menghasilkan NameError
) - setidaknya lakukanexcept OSError:
Biasanya dianggap praktik terbaik untuk hanya menangkap kesalahan yang Anda minati. Dalam hal shutil.rmtree
ini mungkin OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Jika Anda ingin mengabaikan kesalahan itu secara diam-diam, lakukan:
try:
shutil.rmtree(path)
except OSError:
pass
Mengapa? Katakanlah Anda (entah bagaimana) secara tidak sengaja melewatkan fungsi integer alih-alih sebuah string, seperti:
shutil.rmtree(2)
Ini akan memberikan kesalahan "TypeError: memaksa ke Unicode: perlu string atau buffer, int ditemukan" - Anda mungkin tidak ingin mengabaikan itu, yang bisa sulit untuk debug.
Jika Anda benar - benar ingin mengabaikan semua kesalahan, tangkap Exception
daripada except:
pernyataan kosong . Lagi-lagi mengapa?
Tidak menentukan pengecualian menangkap setiap pengecualian, termasuk SystemExit
pengecualian yang misalnya sys.exit()
menggunakan:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Bandingkan ini dengan yang berikut, yang keluar dengan benar:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Jika Anda ingin menulis kode perilaku yang lebih baik, OSError
pengecualian dapat mewakili berbagai kesalahan, tetapi dalam contoh di atas kami hanya ingin mengabaikannya Errno 2
, sehingga kami bisa lebih spesifik:
import errno
try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise
shutil.rmtree
bukan contoh terbaik, karena Anda hanya akan menggunakan ignore_errors=True
untuk fungsi itu ..
Ketika Anda hanya ingin melakukan tangkapan mencoba tanpa menangani pengecualian, bagaimana Anda melakukannya dengan Python?
Itu tergantung pada apa yang Anda maksud dengan "penanganan."
Jika Anda bermaksud menangkapnya tanpa mengambil tindakan apa pun, kode yang Anda poskan akan berfungsi.
Jika Anda bermaksud ingin mengambil tindakan terhadap pengecualian tanpa menghentikan pengecualian dari menumpuk, maka Anda menginginkan sesuatu seperti ini:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Pertama saya kutip jawaban Jack o'Connor dari utas ini . Utas yang dirujuk ditutup jadi saya menulis di sini:
"Ada cara baru untuk melakukan ini dengan Python 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Inilah komit yang menambahkannya: http://hg.python.org/cpython/rev/406b47c64480
Dan inilah pengarangnya, Raymond Hettinger, yang membicarakan hal ini dan semua jenis kepanasan Python lainnya: https://youtu.be/OSGv2VnC0go?t=43m23s
Tambahan saya untuk ini adalah yang setara dengan Python 2.7:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Maka Anda menggunakannya seperti di Python 3.4:
with ignored(Exception):
# your code
Untuk kelengkapan:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
Perhatikan juga bahwa Anda dapat menangkap pengecualian seperti ini:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... dan pasang kembali pengecualian seperti ini:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... contoh dari tutorial python .
Bagaimana cara mengabaikan Pengecualian?
Ada beberapa cara untuk melakukan ini.
Namun, pilihan contoh memiliki solusi sederhana yang tidak mencakup kasus umum.
Dari pada
try:
shutil.rmtree(path)
except:
pass
Melakukan hal ini:
shutil.rmtree(path, ignore_errors=True)
Ini adalah argumen khusus untuk shutil.rmtree
. Anda dapat melihat bantuan tentang itu dengan melakukan hal berikut, dan Anda akan melihatnya juga memungkinkan untuk fungsionalitas pada kesalahan juga.
>>> import shutil
>>> help(shutil.rmtree)
Karena ini hanya mencakup contoh kasus yang sempit, saya akan menunjukkan lebih lanjut bagaimana menangani ini jika argumen kata kunci tersebut tidak ada.
Karena contoh di atas hanya mencakup kasus sempit pada contoh, saya akan menunjukkan lebih lanjut bagaimana menangani hal ini jika argumen kata kunci tersebut tidak ada.
Anda dapat mengimpor suppress
manajer konteks:
from contextlib import suppress
Tetapi hanya menekan pengecualian yang paling spesifik:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Anda akan mengabaikan FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Dari dokumen :
Seperti halnya mekanisme lain yang benar-benar menekan pengecualian, manajer konteks ini harus digunakan hanya untuk menutupi kesalahan yang sangat spesifik di mana diam-diam melanjutkan pelaksanaan program diketahui sebagai hal yang benar untuk dilakukan.
Perhatikan itu suppress
dan FileNotFoundError
hanya tersedia dalam Python 3.
Jika Anda ingin kode Anda berfungsi di Python 2 juga, lihat bagian selanjutnya:
Ketika Anda hanya ingin mencoba / kecuali tanpa menangani pengecualian, bagaimana Anda melakukannya dengan Python?
Apakah mengikuti cara yang benar untuk melakukannya?
try : shutil.rmtree ( path ) except : pass
Untuk kode yang kompatibel dengan Python 2, pass
adalah cara yang benar untuk memiliki pernyataan yang bukan pilihan. Tetapi ketika Anda melakukan telanjang except:
, itu sama seperti melakukan except BaseException:
yang meliputi GeneratorExit
, KeyboardInterrupt
, dan SystemExit
, dan secara umum, Anda tidak ingin menangkap hal-hal.
Bahkan, Anda harus spesifik dalam menyebutkan pengecualian yang Anda bisa.
Inilah bagian dari hierarki pengecualian Python (2) , dan seperti yang Anda lihat, jika Anda menangkap Pengecualian yang lebih umum, Anda dapat menyembunyikan masalah yang tidak Anda harapkan:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Anda mungkin ingin menangkap OSError di sini, dan mungkin pengecualian yang tidak Anda pedulikan adalah jika tidak ada direktori.
Kita bisa mendapatkan bahwa nomor kesalahan tertentu dari errno
perpustakaan, dan reraise jika kita tidak memiliki itu:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Catatan, kenaikan gaji memunculkan pengecualian asli, yang mungkin merupakan apa yang Anda inginkan dalam kasus ini. Ditulis lebih ringkas, karena kita tidak benar-benar perlu secara eksplisit pass
dengan kode dalam penanganan perkecualian:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Ketika Anda hanya ingin melakukan tangkapan mencoba tanpa menangani pengecualian, bagaimana Anda melakukannya dengan Python?
Ini akan membantu Anda untuk mencetak apa pengecualian :( yaitu mencoba menangkap tanpa menangani pengecualian dan mencetak pengecualian.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
FYI klausa lain bisa berlaku setelah semua pengecualian dan hanya akan dijalankan jika kode dalam percobaan tidak menyebabkan pengecualian.
else
dalam konteks ini. Dan untuk menambahkan itu finally
akan selalu berjalan setelah (atau tidak terkecuali).
Saya perlu mengabaikan kesalahan dalam beberapa perintah dan fuckit melakukan trik
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
Dalam Python, kami menangani pengecualian yang mirip dengan bahasa lain, tetapi perbedaannya adalah beberapa perbedaan sintaksis, misalnya,
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...
Saya biasanya hanya melakukan:
try:
doSomething()
except:
_ = ""
_ = ""
dengan pass
.
shutil.rmtree(path, ignore_errors=True)
. Namun, ini tidak berlaku untuk sebagian besar fungsi.