Apakah ini praktik yang baik untuk menggunakan coba-kecuali-yang lain dalam Python?

440

Dari waktu ke waktu dengan Python, saya melihat blok:

try:
   try_this(whatever)
except SomeException as exception:
   #Handle exception
else:
   return something

Apa alasan keberadaan try-kecuali-selain itu ada?

Saya tidak suka pemrograman seperti itu, karena menggunakan pengecualian untuk melakukan kontrol aliran. Namun, jika itu termasuk dalam bahasa, pasti ada alasan bagus untuk itu, bukan?

Ini adalah pemahaman saya bahwa pengecualian bukan kesalahan , dan bahwa mereka hanya boleh digunakan untuk kondisi luar biasa (misalnya saya mencoba menulis file ke disk dan tidak ada ruang lagi, atau mungkin saya tidak memiliki izin), dan bukan untuk aliran kontrol.

Biasanya saya menangani pengecualian sebagai:

something = some_default_value
try:
    something = try_this(whatever)
except SomeException as exception:
    #Handle exception
finally:
    return something

Atau jika saya benar-benar tidak ingin mengembalikan apa pun jika terjadi pengecualian, maka:

try:
    something = try_this(whatever)
    return something
except SomeException as exception:
    #Handle exception
Juan Antonio Gomez Moriano
sumber

Jawaban:

667

"Saya tidak tahu apakah itu karena ketidaktahuan, tapi saya tidak suka pemrograman seperti itu, karena menggunakan pengecualian untuk melakukan kontrol aliran."

Di dunia Python, menggunakan pengecualian untuk kontrol aliran adalah umum dan normal.

Bahkan pengembang inti Python menggunakan pengecualian untuk flow-control dan gaya itu sangat dimasukkan ke dalam bahasa (yaitu protokol iterator menggunakan StopIteration untuk memberi sinyal penghentian loop).

Selain itu, coba-kecuali-gaya digunakan untuk mencegah kondisi ras yang melekat dalam beberapa konstruksi "look-before-you-leap" . Misalnya, pengujian os.path.exists menghasilkan informasi yang mungkin kedaluwarsa pada saat Anda menggunakannya. Demikian juga, Queue.full mengembalikan informasi yang mungkin basi. Gaya coba-kecuali-yang lain akan menghasilkan kode yang lebih andal dalam kasus ini.

"Ini pemahaman saya bahwa pengecualian bukan kesalahan, mereka hanya boleh digunakan untuk kondisi luar biasa"

Dalam beberapa bahasa lain, aturan itu mencerminkan norma budaya mereka sebagaimana tercermin dalam perpustakaan mereka. "Aturan" juga sebagian didasarkan pada pertimbangan kinerja untuk bahasa tersebut.

Norma budaya Python agak berbeda. Dalam banyak kasus, Anda harus menggunakan pengecualian untuk aliran kontrol. Juga, penggunaan pengecualian dalam Python tidak memperlambat kode di sekitarnya dan kode panggilan seperti di beberapa bahasa yang dikompilasi (yaitu CPython sudah mengimplementasikan kode untuk pengecekan pengecualian pada setiap langkah, terlepas dari apakah Anda benar-benar menggunakan pengecualian atau tidak).

Dengan kata lain, pemahaman Anda bahwa "pengecualian untuk yang luar biasa" adalah aturan yang masuk akal dalam beberapa bahasa lain, tetapi tidak untuk Python.

"Namun, jika itu termasuk dalam bahasa itu sendiri, pasti ada alasan yang bagus untuk itu, bukan?"

Selain membantu menghindari kondisi balapan, pengecualian juga sangat berguna untuk menarik loop luar penanganan kesalahan. Ini adalah optimasi yang diperlukan dalam bahasa yang ditafsirkan yang tidak cenderung memiliki gerakan kode invarian loop otomatis .

Selain itu, pengecualian dapat menyederhanakan kode sedikit dalam situasi umum di mana kemampuan untuk menangani suatu masalah jauh dari tempat masalah tersebut muncul. Sebagai contoh, adalah umum untuk memiliki kode panggilan kode antarmuka pengguna tingkat atas untuk logika bisnis yang pada gilirannya memanggil rutin tingkat rendah. Situasi yang timbul dalam rutinitas tingkat rendah (seperti catatan duplikat untuk kunci unik dalam akses basis data) hanya dapat ditangani dalam kode tingkat atas (seperti meminta kunci baru kepada pengguna yang tidak bertentangan dengan kunci yang ada). Penggunaan pengecualian untuk aliran kontrol semacam ini memungkinkan rutinitas tingkat menengah untuk sepenuhnya mengabaikan masalah dan dipisahkan dengan baik dari aspek kontrol aliran tersebut.

Ada posting blog yang bagus tentang perlunya pengecualian di sini .

Juga, lihat jawaban Stack Overflow ini: Apakah pengecualian benar-benar untuk kesalahan luar biasa?

"Apa alasan untuk mencoba-kecuali-yang lain ada?"

Klausa lain itu sendiri menarik. Ini berjalan ketika tidak ada pengecualian kecuali sebelum akhirnya-klausa. Itulah tujuan utamanya.

Tanpa klausa lain, satu-satunya pilihan untuk menjalankan kode tambahan sebelum finalisasi adalah praktik kikuk menambahkan kode ke klausa coba. Itu canggung karena berisiko meningkatkan pengecualian dalam kode yang tidak dimaksudkan untuk dilindungi oleh blok-coba.

Kasus penggunaan menjalankan kode tambahan yang tidak dilindungi sebelum finalisasi tidak sering muncul. Jadi, jangan berharap melihat banyak contoh dalam kode yang diterbitkan. Agak jarang.

Use-case lain untuk klausa lain adalah untuk melakukan tindakan yang harus terjadi ketika tidak ada pengecualian terjadi dan yang tidak terjadi ketika pengecualian ditangani. Sebagai contoh:

recip = float('Inf')
try:
    recip = 1 / f(x)
except ZeroDivisionError:
    logging.info('Infinite result')
else:
    logging.info('Finite result')

Contoh lain terjadi pada pelari yang tidak terdaftar:

try:
    tests_run += 1
    run_testcase(case)
except Exception:
    tests_failed += 1
    logging.exception('Failing test case: %r', case)
    print('F', end='')
else:
    logging.info('Successful test case: %r', case)
    print('.', end='')

Terakhir, penggunaan yang paling umum dari klausa lain dalam blok percobaan adalah untuk sedikit mempercantik (menyelaraskan hasil yang luar biasa dan hasil yang tidak luar biasa pada tingkat indentasi yang sama). Penggunaan ini selalu opsional dan tidak sepenuhnya diperlukan.

Raymond Hettinger
sumber
28
"Itu canggung karena berisiko meningkatkan pengecualian dalam kode yang tidak dimaksudkan untuk dilindungi oleh blok percobaan." Ini adalah pembelajaran terpenting di sini
Felix Dombek
2
Terima kasih atas jawabannya. Untuk pembaca yang mencari contoh penggunaan coba-kecuali-yang lain, lihat metode copyfile shutil github.com/python/cpython/blob/master/Lib/shutil.py#L244
suripoori
2
Intinya adalah bahwa klausa lain hanya dijalankan ketika klausa coba berhasil.
Jonathan
173

Apa alasan keberadaan try-kecuali-selain itu ada?

Sebuah tryblok memungkinkan Anda untuk menangani kesalahan yang diharapkan. The exceptblock hanya harus menangkap pengecualian Anda siap untuk menangani. Jika Anda menangani kesalahan yang tidak terduga, kode Anda mungkin melakukan hal yang salah dan menyembunyikan bug.

Sebuah elseklausa akan dieksekusi jika tidak ada kesalahan, dan dengan tidak mengeksekusi kode itu di tryblok, Anda menghindari menangkap kesalahan yang tidak terduga. Sekali lagi, menangkap kesalahan yang tidak terduga dapat menyembunyikan bug.

Contoh

Sebagai contoh:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
else:
    return something

Suite "coba, kecuali" memiliki dua klausa opsional, elsedan finally. Jadi sebenarnya try-except-else-finally.

elseakan mengevaluasi hanya jika tidak ada pengecualian dari tryblok. Ini memungkinkan kami untuk menyederhanakan kode yang lebih rumit di bawah ini:

no_error = None
try:
    try_this(whatever)
    no_error = True
except SomeException as the_exception:
    handle(the_exception)
if no_error:
    return something

jadi jika kita membandingkan suatu elsedengan alternatif (yang mungkin membuat bug) kita melihat bahwa itu mengurangi garis-garis kode dan kita dapat memiliki basis kode yang lebih mudah dibaca, dirawat, dan kurang buggy.

finally

finally akan mengeksekusi tidak peduli apa, bahkan jika baris lain sedang dievaluasi dengan pernyataan pengembalian.

Rusak dengan kode semu

Mungkin membantu untuk memecah ini, dalam bentuk sekecil mungkin yang menunjukkan semua fitur, dengan komentar. Anggap ini benar secara sintaksis (tetapi tidak bisa dijalankan kecuali nama-nama didefinisikan) pseudo-code dalam suatu fungsi.

Sebagai contoh:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle_SomeException(the_exception)
    # Handle a instance of SomeException or a subclass of it.
except Exception as the_exception:
    generic_handle(the_exception)
    # Handle any other exception that inherits from Exception
    # - doesn't include GeneratorExit, KeyboardInterrupt, SystemExit
    # Avoid bare `except:`
else: # there was no exception whatsoever
    return something()
    # if no exception, the "something()" gets evaluated,
    # but the return will not be executed due to the return in the
    # finally block below.
finally:
    # this block will execute no matter what, even if no exception,
    # after "something" is eval'd but before that value is returned
    # but even if there is an exception.
    # a return here will hijack the return functionality. e.g.:
    return True # hijacks the return in the else clause above

Memang benar bahwa kita dapat memasukkan kode dalam elseblok di tryblok sebagai gantinya, di mana ia akan berjalan jika tidak ada pengecualian, tetapi bagaimana jika kode itu sendiri menimbulkan pengecualian dari jenis yang kita tangkap? Membiarkannya di tryblok akan menyembunyikan bug itu.

Kami ingin meminimalkan baris kode di tryblok untuk menghindari penangkapan pengecualian yang tidak kami harapkan, dengan prinsip bahwa jika kode kami gagal, kami ingin kode tersebut gagal dengan keras. Ini adalah praktik terbaik .

Ini adalah pemahaman saya bahwa pengecualian bukan kesalahan

Dalam Python, sebagian besar pengecualian adalah kesalahan.

Kita dapat melihat hierarki pengecualian dengan menggunakan pydoc. Misalnya, dalam Python 2:

$ python -m pydoc exceptions

atau Python 3:

$ python -m pydoc builtins

Akan memberi kita hierarki. Kita dapat melihat bahwa sebagian besar jenis Exceptionkesalahan, meskipun Python menggunakan beberapa dari mereka untuk hal-hal seperti mengakhiri forloop ( StopIteration). Ini adalah hierarki Python 3:

BaseException
    Exception
        ArithmeticError
            FloatingPointError
            OverflowError
            ZeroDivisionError
        AssertionError
        AttributeError
        BufferError
        EOFError
        ImportError
            ModuleNotFoundError
        LookupError
            IndexError
            KeyError
        MemoryError
        NameError
            UnboundLocalError
        OSError
            BlockingIOError
            ChildProcessError
            ConnectionError
                BrokenPipeError
                ConnectionAbortedError
                ConnectionRefusedError
                ConnectionResetError
            FileExistsError
            FileNotFoundError
            InterruptedError
            IsADirectoryError
            NotADirectoryError
            PermissionError
            ProcessLookupError
            TimeoutError
        ReferenceError
        RuntimeError
            NotImplementedError
            RecursionError
        StopAsyncIteration
        StopIteration
        SyntaxError
            IndentationError
                TabError
        SystemError
        TypeError
        ValueError
            UnicodeError
                UnicodeDecodeError
                UnicodeEncodeError
                UnicodeTranslateError
        Warning
            BytesWarning
            DeprecationWarning
            FutureWarning
            ImportWarning
            PendingDeprecationWarning
            ResourceWarning
            RuntimeWarning
            SyntaxWarning
            UnicodeWarning
            UserWarning
    GeneratorExit
    KeyboardInterrupt
    SystemExit

Seorang komentator bertanya:

Katakanlah Anda memiliki metode yang mem-ping API eksternal dan Anda ingin menangani pengecualian pada kelas di luar pembungkus API, apakah Anda hanya mengembalikan e dari metode di bawah klausa kecuali di mana e adalah objek pengecualian?

Tidak, Anda tidak mengembalikan pengecualian, hanya jalankan kembali dengan telanjang raiseuntuk mempertahankan stacktrace.

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    raise

Atau, dalam Python 3, Anda bisa menaikkan pengecualian baru dan mempertahankan backtrace dengan rantai pengecualian:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    raise DifferentException from the_exception

Saya menguraikan jawaban saya di sini .

Aaron Hall
sumber
terbalik! apa yang biasanya Anda lakukan di dalam bagian pegangan? katakanlah Anda memiliki metode yang mem-ping API eksternal dan Anda ingin menangani pengecualian pada kelas di luar pembungkus API, apakah Anda cukup mengembalikan e dari metode di bawah klausa kecuali di mana e adalah objek pengecualian?
PirateApp
1
@ PirateApp terima kasih! tidak, jangan kembalikan, Anda mungkin harus melakukan rareise dengan telanjang raiseatau melakukan chaining pengecualian - tapi itu lebih pada topik dan dibahas di sini: stackoverflow.com/q/2052390/541136 - Saya mungkin akan menghapus komentar ini setelah saya sudah melihat kamu telah melihat mereka.
Aaron Hall
terima kasih banyak untuk detailnya! melalui pos sekarang
PirateApp
36

Python tidak berlangganan gagasan bahwa pengecualian hanya boleh digunakan untuk kasus luar biasa, pada kenyataannya idiomnya adalah 'minta maaf, bukan izin' . Ini berarti bahwa menggunakan pengecualian sebagai bagian rutin dari kontrol aliran Anda dapat diterima, dan pada kenyataannya, dianjurkan.

Ini umumnya hal yang baik, karena bekerja dengan cara ini membantu menghindari beberapa masalah (sebagai contoh nyata, kondisi lomba sering dihindari), dan cenderung membuat kode sedikit lebih mudah dibaca.

Bayangkan Anda memiliki situasi di mana Anda mengambil beberapa input pengguna yang perlu diproses, tetapi memiliki default yang sudah diproses. The try: ... except: ... else: ...Struktur membuat kode sangat mudah dibaca:

try:
   raw_value = int(input())
except ValueError:
   value = some_processed_value
else: # no error occured
   value = process_value(raw_value)

Bandingkan dengan cara kerjanya dalam bahasa lain:

raw_value = input()
if valid_number(raw_value):
    value = process_value(int(raw_value))
else:
    value = some_processed_value

Perhatikan keunggulannya. Tidak perlu memeriksa nilai yang valid dan menguraikannya secara terpisah, mereka dilakukan sekali. Kode juga mengikuti perkembangan yang lebih logis, jalur kode utama pertama, diikuti oleh 'jika tidak berhasil, lakukan ini'.

Contohnya secara alami sedikit dibuat-buat, tetapi itu menunjukkan ada kasus untuk struktur ini.

Gareth Latty
sumber
15

Apakah ini praktik yang baik untuk menggunakan coba-kecuali-yang lain dalam python?

Jawabannya adalah tergantung pada konteks. Jika kamu melakukan ini:

d = dict()
try:
    item = d['item']
except KeyError:
    item = 'default'

Ini menunjukkan bahwa Anda tidak mengenal Python dengan baik. Fungsi ini diringkas dalam dict.getmetode:

item = d.get('item', 'default')

Itu try / exceptblok adalah cara yang jauh lebih visual berantakan dan verbose menulis apa yang bisa efisien mengeksekusi dalam satu baris dengan metode atom. Ada kasus lain di mana ini benar.

Namun, itu tidak berarti bahwa kita harus menghindari semua penanganan pengecualian. Dalam beberapa kasus lebih disukai untuk menghindari kondisi balapan. Jangan periksa apakah ada file, coba buka saja, dan tangkap IOError yang sesuai. Demi kesederhanaan dan keterbacaan, cobalah untuk merangkum ini atau faktor itu sebagai yang sesuai.

Baca Zen Python , pahami bahwa ada prinsip-prinsip yang berada dalam ketegangan, dan waspadalah terhadap dogma yang terlalu bergantung pada salah satu pernyataan di dalamnya.

Aaron Hall
sumber
12

Lihat contoh berikut yang mengilustrasikan segala sesuatu tentang coba-kecuali-lain-akhirnya:

for i in range(3):
    try:
        y = 1 / i
    except ZeroDivisionError:
        print(f"\ti = {i}")
        print("\tError report: ZeroDivisionError")
    else:
        print(f"\ti = {i}")
        print(f"\tNo error report and y equals {y}")
    finally:
        print("Try block is run.")

Implementasikan dan datang dengan:

    i = 0
    Error report: ZeroDivisionError
Try block is run.
    i = 1
    No error report and y equals 1.0
Try block is run.
    i = 2
    No error report and y equals 0.5
Try block is run.
Kalkulus
sumber
3
Ini adalah contoh yang bagus dan sederhana yang dengan cepat menunjukkan klausa percobaan penuh tanpa mengharuskan seseorang (yang mungkin sedang terburu-buru) untuk membaca penjelasan abstrak yang panjang. (Tentu saja, ketika mereka tidak sedang terburu-buru lagi, mereka harus kembali dan membaca abstrak lengkapnya.)
GlobalSoftwareSociety
6

Anda harus berhati-hati dalam menggunakan blok akhirnya, karena itu tidak sama dengan menggunakan blok lain di coba, kecuali. Blok akhirnya akan dijalankan terlepas dari hasil percobaan kecuali.

In [10]: dict_ = {"a": 1}

In [11]: try:
   ....:     dict_["b"]
   ....: except KeyError:
   ....:     pass
   ....: finally:
   ....:     print "something"
   ....:     
something

Karena semua orang telah mencatat menggunakan blok lain menyebabkan kode Anda lebih mudah dibaca, dan hanya berjalan ketika pengecualian tidak dilempar

In [14]: try:
             dict_["b"]
         except KeyError:
             pass
         else:
             print "something"
   ....:
Greg
sumber
Saya tahu bahwa akhirnya selalu dieksekusi, dan itulah sebabnya hal itu dapat digunakan untuk keuntungan kita dengan selalu menetapkan nilai default, jadi jika pengecualian dikembalikan, jika kita tidak ingin mengembalikan nilai tersebut jika terkecuali, itu sudah cukup untuk menghapus blok terakhir. Btw, menggunakan umpan terobosan adalah sesuatu yang tidak akan pernah saya lakukan :)
Juan Antonio Gomez Moriano
@Juan Antonio Gomez Moriano, blok kode saya hanya untuk keperluan contoh. Saya mungkin tidak akan pernah menggunakan pass
Greg
4

Setiap kali Anda melihat ini:

try:
    y = 1 / x
except ZeroDivisionError:
    pass
else:
    return y

Atau bahkan ini:

try:
    return 1 / x
except ZeroDivisionError:
    return None

Pertimbangkan ini sebagai gantinya:

import contextlib
with contextlib.suppress(ZeroDivisionError):
    return 1 / x
Rajiv Bakulesh Shah
sumber
1
Itu tidak menjawab pertanyaan saya, karena itu hanya contoh teman saya.
Juan Antonio Gomez Moriano
Dalam Python, pengecualian bukan kesalahan. Mereka bahkan tidak luar biasa. Dalam Python, normal dan alami untuk menggunakan pengecualian untuk kontrol aliran. Ini dibuktikan dengan dimasukkannya contextlib.suppress () di perpustakaan standar. Lihat jawaban Raymond Hettinger di sini: stackoverflow.com/a/16138864/1197429 (Raymond adalah kontributor utama Python, dan otoritas untuk semua hal Pythonic!)
Rajiv Bakulesh Shah
4

Hanya karena tidak ada orang lain yang memposting pendapat ini, saya akan mengatakan

hindari elseklausul try/excepts karena mereka tidak dikenal oleh kebanyakan orang

Berbeda dengan kata kunci try,, exceptdan finally, makna elseklausa tidak jelas; itu kurang mudah dibaca. Karena tidak sering digunakan, itu akan menyebabkan orang yang membaca kode Anda ingin memeriksa ulang dokumen untuk memastikan mereka memahami apa yang terjadi.

(Saya menulis jawaban ini justru karena saya menemukan try/except/elsedi basis kode saya dan itu menyebabkan wtf saat dan memaksa saya untuk melakukan beberapa pencarian di Google).

Jadi, di mana pun saya melihat kode seperti contoh OP:

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
else:
    # do some more processing in non-exception case
    return something

Saya lebih suka refactor

try:
    try_this(whatever)
except SomeException as the_exception:
    handle(the_exception)
    return  # <1>
# do some more processing in non-exception case  <2>
return something
  • <1> pengembalian eksplisit, dengan jelas menunjukkan bahwa, dalam kasus pengecualian, kami selesai bekerja

  • <2> sebagai efek samping minor yang bagus, kode yang dulunya berada di elseblok disimpulkan oleh satu level.

hwjp
sumber
1
Argumen iblis kontra-argumen: semakin banyak orang menggunakannya, akan semakin baik adopsi itu. Hanya makanan untuk dipikirkan, meskipun saya setuju bahwa keterbacaan adalah impor. Yang mengatakan, begitu seseorang memahami coba-lagi, saya berpendapat bahwa itu jauh lebih mudah dibaca daripada alternatif dalam banyak kasus.
bob
2

Ini adalah cuplikan sederhana saya tentang cara memahami blok coba-kecuali-lain-akhirnya di Python:

def div(a, b):
    try:
        a/b
    except ZeroDivisionError:
        print("Zero Division Error detected")
    else:
        print("No Zero Division Error")
    finally:
        print("Finally the division of %d/%d is done" % (a, b))

Mari coba div 1/1:

div(1, 1)
No Zero Division Error
Finally the division of 1/1 is done

Mari coba div 1/0

div(1, 0)
Zero Division Error detected
Finally the division of 1/0 is done
zakiakhmad
sumber
1
Saya pikir ini gagal untuk memberikan contoh mengapa Anda tidak bisa begitu saja memasukkan kode lain ke dalam percobaan
Mojimi
-4

OP, ANDA BENAR. Yang lain setelah mencoba / kecuali dalam Python jelek . itu mengarah ke objek kontrol aliran lain di mana tidak ada yang diperlukan:

try:
    x = blah()
except:
    print "failed at blah()"
else:
    print "just succeeded with blah"

Setara yang sangat jelas adalah:

try:
    x = blah()
    print "just succeeded with blah"
except:
    print "failed at blah()"

Ini jauh lebih jelas daripada klausa lain. Yang lain setelah mencoba / kecuali tidak sering ditulis, sehingga perlu beberapa saat untuk mengetahui apa implikasinya.

Hanya karena Anda BISA melakukan sesuatu, tidak berarti Anda HARUS melakukan sesuatu.

Banyak fitur telah ditambahkan ke bahasa karena seseorang mengira itu mungkin berguna. Masalahnya adalah, semakin banyak fitur, hal-hal yang kurang jelas dan jelas adalah karena orang biasanya tidak menggunakan bel dan peluit itu.

Hanya 5 sen saya di sini. Saya harus ikut serta dan membersihkan banyak kode yang ditulis oleh mahasiswa tahun pertama dari pengembang perguruan tinggi yang berpikir mereka cerdas dan ingin menulis kode dengan cara yang ketat, sangat efisien ketika itu hanya membuatnya berantakan untuk mencoba dan membaca / memodifikasi nanti. Saya memilih keterbacaan setiap hari dan dua kali pada hari Minggu.

Kevin J. Rice
sumber
15
Kamu benar. Benar-benar jelas dan setara ... kecuali printpernyataan Anda yang gagal. Apa yang terjadi jika x = blah()mengembalikan a str, tetapi pernyataan cetak Anda print 'just succeeded with blah. x == %d' % x? Sekarang Anda memiliki hasil TypeErroryang dibuat di mana Anda tidak siap untuk menanganinya; Anda sedang memeriksa x = blah()untuk menemukan sumber pengecualian, dan bahkan tidak ada di sana. Saya telah melakukan ini (atau yang setara) lebih dari sekali di mana elsesaya tidak akan melakukan kesalahan ini. Sekarang saya tahu lebih baik. :-D
Doug R.
2
... dan ya, kamu benar. The elseklausul bukanlah pernyataan yang cukup, dan sampai Anda terbiasa untuk itu, itu tidak intuitif. Tapi kemudian, begitu juga finallyketika saya pertama kali mulai menggunakannya ...
Doug R.
2
Untuk menggemakan Doug R., itu tidak setara karena pengecualian selama pernyataan dalam elseklausa tidak ditangkap oleh except.
alastair
jika ... kecuali ... yang lain lebih mudah dibaca, jika tidak Anda harus membaca "oh, setelah coba blok, dan tidak terkecuali, buka pernyataan di luar blok coba", jadi gunakan yang lain: cenderung sedikit semantik menghubungkan sintaksis lebih baik imo. Selain itu, praktik yang baik adalah membiarkan pernyataan Anda yang tidak terkunci di luar blok percobaan awal.
cowbert
1
@DougR. "Anda sedang memeriksa x = blah()untuk menemukan sumber pengecualian", Setelah tracebackmengapa Anda memeriksa sumber pengecualian dari tempat yang salah?
nehem