Periksa Penanganan Pertama vs Pengecualian?

88

Saya sedang mengerjakan buku "Head First Python" (ini bahasa saya untuk belajar tahun ini) dan saya sampai di bagian di mana mereka berdebat tentang dua teknik kode:
Memeriksa penanganan Pertama vs Pengecualian.

Berikut ini contoh kode Python:

# Checking First
for eachLine in open("../../data/sketch.txt"):
    if eachLine.find(":") != -1:
        (role, lineSpoken) = eachLine.split(":",1)
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())

# Exception handling        
for eachLine in open("../../data/sketch.txt"):
    try:
        (role, lineSpoken) = eachLine.split(":",1)
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())
    except:
        pass

Contoh pertama berkaitan langsung dengan masalah dalam .splitfungsi. Yang kedua hanya memungkinkan penanganan handler pengecualian dengan itu (dan mengabaikan masalahnya).

Mereka berdebat dalam buku ini untuk menggunakan penanganan pengecualian alih-alih memeriksa terlebih dahulu. Argumennya adalah bahwa kode pengecualian akan menangkap semua kesalahan, di mana pengecekan pertama hanya akan menangkap hal-hal yang Anda pikirkan (dan Anda melewatkan kasus sudut). Saya telah diajari untuk memeriksanya terlebih dahulu, jadi insting awal saya adalah melakukan itu, tetapi ide mereka menarik. Saya tidak pernah berpikir untuk menggunakan penanganan pengecualian untuk menangani kasus.

Manakah dari keduanya yang secara umum dianggap praktik yang lebih baik?

jmq
sumber
12
Bagian dalam buku itu tidak cerdas. Jika Anda berada dalam satu lingkaran dan Anda melempar pengecualian berulang sangat mahal. Saya mencoba menguraikan beberapa poin bagus kapan harus melakukan ini.
Jason Sebring
9
Hanya saja, jangan jatuh ke dalam perangkap "file exist check". File ada! = Memiliki akses ke file, atau akan ada dalam 10 ms yang diperlukan untuk sampai ke panggilan buka file saya, dll. Blogs.msdn.com/b/jaredpar/archive/2009/04/27/…
Billy ONeal
11
Pengecualian dianggap berbeda dalam Python dibandingkan dalam bahasa lain. Misalnya cara untuk mengulang melalui koleksi adalah dengan memanggil .next () di atasnya sampai ia melempar pengecualian.
WuHoUnited
4
@ emeraldcode.com Itu tidak sepenuhnya benar tentang Python. Saya tidak tahu secara spesifik, tetapi bahasanya telah dibangun di sekitar paradigma itu, jadi melempar pengecualian tidak semahal di bahasa lain.
Izkata
Yang mengatakan, untuk contoh ini, saya akan menggunakan pernyataan penjaga:, if -1 == eachLine.find(":"): continuemaka sisa dari loop tidak akan di-indentasi juga.
Izkata

Jawaban:

68

Di .NET, itu adalah praktik umum untuk menghindari terlalu banyak Pengecualian. Salah satu argumen adalah kinerja: di .NET, melemparkan pengecualian adalah mahal secara komputasi.

Alasan lain untuk menghindari penggunaan berlebihan mereka adalah karena bisa sangat sulit untuk membaca kode yang terlalu mengandalkan mereka. Entri blog Joel Spolsky melakukan pekerjaan yang baik untuk menggambarkan masalah ini.

Inti dari argumen ini adalah kutipan berikut:

Alasannya adalah bahwa saya menganggap pengecualian tidak lebih baik daripada "goto's", yang dianggap berbahaya sejak 1960-an, karena mereka membuat lompatan tiba-tiba dari satu titik kode ke titik lainnya. Bahkan mereka secara signifikan lebih buruk daripada goto:

1. Mereka tidak terlihat dalam kode sumber . Melihat sekumpulan kode, termasuk fungsi yang bisa atau tidak melempar pengecualian, tidak ada cara untuk melihat pengecualian mana yang dilempar dan dari mana. Ini berarti bahwa pemeriksaan kode yang teliti sekalipun tidak mengungkapkan potensi bug.

2. Mereka membuat terlalu banyak kemungkinan titik keluar untuk suatu fungsi. Untuk menulis kode yang benar, Anda benar-benar harus memikirkan setiap jalur kode yang mungkin melalui fungsi Anda. Setiap kali Anda memanggil fungsi yang dapat meningkatkan pengecualian dan tidak langsung menangkapnya, Anda menciptakan peluang untuk bug kejutan yang disebabkan oleh fungsi yang diakhiri secara tiba-tiba, meninggalkan data dalam keadaan tidak konsisten, atau jalur kode lain yang tidak Anda temui. memikirkan tentang.

Secara pribadi, saya melempar pengecualian ketika kode saya tidak dapat melakukan apa yang dikontrak. Saya cenderung menggunakan try / catch ketika saya akan berurusan dengan sesuatu di luar batas proses saya, misalnya panggilan SOAP, panggilan database, file IO, atau panggilan sistem. Kalau tidak, saya mencoba kode pertahanan. Ini bukan aturan yang keras dan cepat, tetapi itu adalah praktik umum.

Scott Hanselman juga menulis tentang pengecualian di .NET di sini . Dalam artikel ini ia menjelaskan beberapa aturan praktis tentang pengecualian. Kesukaan saya?

Anda tidak boleh melempar pengecualian untuk hal-hal yang terjadi sepanjang waktu. Maka mereka akan menjadi "ordinaris".

Kyle Hodgson
sumber
5
inilah poin lain: jika penebangan pengecualian diaktifkan di seluruh aplikasi, lebih baik menggunakan pengecualian hanya untuk kondisi luar biasa, bukan untuk tata cara. Kalau tidak, log akan menjadi berantakan dan alasan penyebab kesalahan nyata akan dikaburkan.
rwong
2
Jawaban bagus. Perhatikan bahwa pengecualian memiliki hit kinerja tinggi di sebagian besar platform. Namun, seperti yang akan Anda catat dengan komentar saya pada jawaban lain, kinerja bukanlah pertimbangan dalam hal memutuskan aturan selimut untuk cara mengkodifikasikan sesuatu.
mattnz
1
Kutipan dari Scott Hanselman lebih baik menggambarkan sikap. Net terhadap pengecualian daripada "berlebihan". Kinerja sering disebutkan, tetapi argumen sebenarnya adalah kebalikan dari mengapa Anda HARUS menggunakan pengecualian - itu membuat kode lebih sulit untuk dipahami dan ditangani ketika kondisi biasa menghasilkan pengecualian. Sedangkan untuk Joel, poin 1 sebenarnya positif (tidak terlihat berarti kode menunjukkan apa yang dilakukannya, bukan apa yang tidak), dan poin 2 tidak relevan (Anda sudah dalam keadaan tidak konsisten, atau seharusnya tidak ada pengecualian) . Namun, +1 untuk "tidak dapat melakukan apa yang diminta untuk dilakukan".
jmoreno
5
Meskipun jawaban ini baik untuk .Net, itu tidak terlalu pythonic , jadi mengingat ini adalah pertanyaan python, saya gagal untuk melihat mengapa jawaban Ivc belum terpilih.
Mark Booth
2
@IanGoldby: tidak. Penanganan pengecualian sebenarnya lebih baik digambarkan sebagai pengecualian pemulihan. Jika Anda tidak dapat memulihkan dari pengecualian, maka Anda mungkin seharusnya tidak memiliki kode penanganan pengecualian. Jika metode A memanggil metode B yang memanggil C, dan C melempar, maka kemungkinan besar BAIK A ATAU B akan pulih, bukan keduanya. Keputusan "jika saya tidak bisa melakukan X saya akan melakukan Y" harus dihindari jika Y meminta orang lain untuk menyelesaikan tugas. Jika Anda tidak dapat menyelesaikan tugas, yang tersisa hanyalah pembersihan dan pencatatan. Pembersihan .net harus otomatis, logging harus terpusat.
jmoreno
78

Dalam Python khususnya, biasanya dianggap praktik yang lebih baik untuk menangkap pengecualian. Itu cenderung disebut Lebih Mudah untuk Meminta Pengampunan daripada Izin (EAFP), dibandingkan dengan Look Before You Leap (LBYL). Ada beberapa kasus di mana LBYL akan memberi Anda bug halus dalam beberapa kasus.

Namun, berhati-hatilah dengan except:pernyataan telanjang dan terlalu banyak kecuali pernyataan, karena keduanya bisa juga menutupi bug - sesuatu seperti ini akan lebih baik:

for eachLine in open("../../data/sketch.txt"):
    try:
        role, lineSpoken = eachLine.split(":",1)
    except ValueError:
        pass
    else:
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())
lvc
sumber
8
Sebagai pemrogram .NET, saya merasa ngeri mendengarnya. Tapi sekali lagi, kalian melakukan semua yang aneh. :)
Phil
Ini sangat membuat frustasi (tidak dimaksudkan) ketika API tidak konsisten tentang pengecualian mana yang dilemparkan dalam kondisi apa, atau ketika berbagai jenis kegagalan dilemparkan di bawah tipe pengecualian yang sama.
Jack
Jadi Anda akhirnya menggunakan mekanisme yang sama untuk kesalahan tak terduga dan nilai pengembalian yang diharapkan. Itu sama baiknya dengan menggunakan 0 sebagai angka, bool palsu, DAN penunjuk yang tidak valid yang akan keluar dari proses Anda dengan kode keluar 128 + SIGSEGV, karena betapa nyamannya, Anda tidak memerlukan hal-hal yang berbeda sekarang. Seperti spork! Atau sepatu dengan jari kaki ...
yeoman
2
@Yoman ketika melempar pengecualian adalah pertanyaan yang berbeda, yang ini adalah tentang menggunakan try/ exceptdaripada menyiapkan persyaratan untuk "adalah kemungkinan berikut untuk melempar pengecualian", dan latihan Python pasti lebih memilih yang sebelumnya. Tidak ada salahnya bahwa pendekatan itu (mungkin) lebih efisien di sini, karena, dalam kasus di mana perpecahan berhasil, Anda hanya menjalankan string sekali. Seperti apakah splitharus melempar pengecualian di sini, saya akan mengatakan itu pasti harus - satu aturan umum adalah Anda harus melempar ketika Anda tidak bisa melakukan apa yang nama Anda katakan, dan Anda tidak bisa membagi pada pembatas yang hilang.
lvc
Saya tidak menemukan itu buruk atau lambat atau mengerikan, terutama karena hanya pengecualian khusus yang ditangkap. Saya sebenarnya suka Python. Hanya lucu bagaimana kadang-kadang tidak menunjukkan rasa sama sekali, seperti kata C menggunakan nomor nol, Spork, dan sepatu favorit sepanjang masa Randall Munroe dengan jari kaki :) Plus, ketika saya menggunakan Python dan API mengatakan ini adalah cara untuk melakukannya, saya akan pergi untuk itu :) Memeriksa kondisi di muka tentu saja tidak pernah merupakan ide yang baik karena konkurensi, coroutine, atau salah satu dari mereka yang ditambahkan lebih jauh ...
yeoman
27

Pendekatan Pragmatis

Anda harus bersikap defensif tetapi to the point. Anda harus menulis penanganan perkecualian tetapi tidak langsung. Saya akan menggunakan pemrograman web sebagai contoh karena ini adalah tempat tinggal saya.

  1. Asumsikan semua input pengguna buruk dan menulis defensif hanya ke titik verifikasi tipe data, pemeriksaan pola dan injeksi berbahaya. Pemrograman defensif haruslah hal-hal yang berpotensi terjadi sangat sering yang tidak dapat Anda kendalikan.
  2. Tuliskan penanganan pengecualian untuk layanan jaringan yang mungkin gagal di kali dan menangani dengan anggun untuk umpan balik pengguna. Pemrograman pengecualian harus digunakan untuk hal-hal jaringan yang mungkin gagal dari waktu ke waktu tetapi biasanya solid DAN Anda perlu menjaga program Anda bekerja.
  3. Jangan repot-repot menulis secara defensif dalam aplikasi Anda setelah data input telah divalidasi. Buang-buang waktu dan gembung aplikasi Anda. Biarkan itu meledak karena itu adalah sesuatu yang sangat jarang yang tidak layak ditangani atau itu berarti Anda perlu melihat langkah 1 dan 2 dengan lebih hati-hati.
  4. Jangan pernah menulis penanganan pengecualian dalam kode inti Anda yang tidak bergantung pada perangkat jaringan. Melakukannya adalah pemrograman yang buruk dan mahal untuk kinerja. Misalnya menulis try-catch jika array di luar batas dalam satu lingkaran berarti Anda tidak memprogram loop dengan benar di tempat pertama.
  5. Biarkan semuanya ditangani oleh pencatatan kesalahan pusat yang menangkap pengecualian di satu tempat setelah mengikuti prosedur di atas. Anda tidak dapat menangkap setiap kasus tepi karena itu mungkin tak terbatas, Anda hanya perlu menulis kode yang menangani operasi yang diharapkan. Itu sebabnya Anda menggunakan penanganan kesalahan pusat sebagai pilihan terakhir.
  6. TDD bagus karena cara mencoba menangkap Anda tanpa mengasapi, yang berarti memberi Anda jaminan operasi normal.
  7. Poin bonus adalah dengan menggunakan alat cakupan kode misalnya Istanbul adalah yang bagus untuk simpul karena ini menunjukkan di mana Anda tidak menguji.
  8. Peringatan untuk semua ini adalah pengecualian yang ramah pengembang . Misalnya, bahasa akan dilempar jika Anda menggunakan sintaks yang salah dan menjelaskan alasannya. Jadi seharusnya utilitas Anda perpustakaan yang bergantung pada sebagian besar kode Anda.

Ini dari pengalaman bekerja dalam skenario tim besar.

Analogi

Bayangkan jika Anda mengenakan pakaian luar angkasa di ISS ALL ALL the time. Akan sulit untuk pergi ke kamar mandi atau makan, sama sekali. Akan sangat besar di dalam modul luar angkasa untuk bergerak. Itu akan payah. Menulis banyak try-catch di dalam kode Anda adalah semacam itu. Anda harus memiliki titik di mana Anda mengatakan, hei saya mengamankan ISS dan astronot saya di dalam tidak apa-apa jadi tidak praktis untuk memakai baju ruang angkasa untuk setiap skenario yang mungkin terjadi.

Jason Sebring
sumber
4
Masalah dengan Point 3 adalah mengasumsikan program, dan programmer yang mengerjakannya, adalah sempurna. Mereka tidak, jadi ini program terbaik untuk mempertahankan hal ini. Jumlah yang tepat pada titik waktu utama dapat membuat perangkat lunak jauh lebih andal daripada mentalitas "Jika input diperiksa semuanya sempurna".
mattnz
untuk itulah pengujian dilakukan.
Jason Sebring
3
Pengujian bukanlah hal yang mudah. Saya belum melihat test suite yang memiliki 100% kode dan cakupan "lingkungan".
Marjan Venema
1
@emeraldcode: Apakah Anda ingin bekerja dengan saya, saya akan senang memiliki seseorang di tim yang selalu, dengan pengecualian, menguji setiap permutasi dari setiap kasus tepi perangkat lunak yang akan pernah dijalankan. Pasti menyenangkan mengetahui dengan kepastian abosoluite bahwa kode Anda diuji dengan sempurna.
mattnz
1
Setuju. Ada beberapa skenario yang baik pemrograman defensif dan penanganan pengecualian bekerja dengan baik dan buruk, dan kita sebagai programmer harus belajar mengenalinya, dan memilih teknik yang paling cocok. Saya suka Poin 3 karena saya percaya kita perlu mengasumsikan, pada tingkat tertentu kode, bahwa beberapa kondisi kontekstual harus dipenuhi. Kondisi ini dipenuhi dengan pengkodean secara defensif di lapisan luar kode, dan saya pikir penanganan pengecualian cocok ketika asumsi ini rusak di lapisan dalam.
yaobin
15

Argumen utama buku ini adalah bahwa versi pengecualian kode lebih baik karena akan menangkap apa pun yang mungkin Anda abaikan jika Anda mencoba menulis pengecekan kesalahan sendiri.

Saya pikir pernyataan ini benar hanya dalam keadaan yang sangat spesifik - di mana Anda tidak peduli jika hasilnya benar.

Tidak ada keraguan bahwa mengajukan pengecualian adalah praktik yang sehat dan aman. Anda harus melakukannya kapan pun Anda merasa ada sesuatu dalam kondisi saat ini dari program yang Anda (sebagai pengembang) tidak bisa, atau tidak ingin, atasi.

Namun, contoh Anda adalah tentang menangkap pengecualian. Jika Anda menangkap pengecualian, Anda tidak melindungi diri dari skenario yang mungkin Anda abaikan. Anda melakukan sebaliknya: Anda berasumsi bahwa Anda tidak mengabaikan skenario apa pun yang mungkin menyebabkan jenis pengecualian ini, dan karena itu Anda yakin bahwa tidak apa-apa untuk menangkapnya (dan dengan demikian mencegahnya menyebabkan program keluar, sebagai pengecualian tanpa tertangkap akan).

Menggunakan pendekatan pengecualian, jika Anda melihat ValueErrorpengecualian, Anda melewatkan satu baris. Menggunakan pendekatan non-pengecualian tradisional, Anda menghitung jumlah nilai yang dikembalikan dari split, dan jika kurang dari 2, Anda melewatkan satu baris. Jika Anda merasa lebih aman dengan pendekatan pengecualian, karena Anda mungkin telah melupakan beberapa situasi "kesalahan" lain dalam pemeriksaan kesalahan tradisional Anda, dan except ValueErrorakan menangkapnya untuk Anda?

Ini tergantung pada sifat program Anda.

Jika Anda menulis, misalnya, peramban web atau pemutar video, masalah dengan input tidak boleh menyebabkannya rusak dengan pengecualian yang tidak tertangkap. Jauh lebih baik untuk mengeluarkan sesuatu yang masuk akal (bahkan jika, sebenarnya, salah) daripada berhenti.

Jika Anda menulis aplikasi di mana kebenarannya penting (seperti perangkat lunak bisnis atau rekayasa), ini akan menjadi pendekatan yang mengerikan. Jika Anda lupa tentang beberapa skenario yang muncul ValueError, hal terburuk yang dapat Anda lakukan adalah mengabaikan skenario yang tidak diketahui ini secara diam-diam dan lewati saja. Begitulah bug yang sangat halus dan mahal berakhir di perangkat lunak.

Anda mungkin berpikir bahwa satu-satunya cara Anda dapat melihat ValueErrordalam kode ini, adalah jika splitdikembalikan hanya satu nilai (bukan dua). Tetapi bagaimana jika printpernyataan Anda kemudian mulai menggunakan ekspresi yang muncul ValueErrordalam beberapa kondisi? Ini akan menyebabkan Anda melewatkan beberapa baris bukan karena mereka ketinggalan :, tetapi karena printgagal pada mereka. Ini adalah contoh bug halus yang saya maksudkan sebelumnya - Anda tidak akan melihat apa-apa, hanya kehilangan beberapa baris.

Rekomendasi saya adalah untuk menghindari menangkap (tetapi tidak menaikkan!) Pengecualian dalam kode di mana menghasilkan output yang salah lebih buruk daripada keluar. Satu-satunya waktu saya menangkap pengecualian dalam kode tersebut adalah ketika saya memiliki ekspresi yang benar-benar sepele, jadi saya dapat dengan mudah alasan apa yang menyebabkan masing-masing jenis pengecualian yang mungkin.

Mengenai dampak kinerja menggunakan pengecualian, itu sepele (dengan Python) kecuali pengecualian yang sering ditemui.

Jika Anda menggunakan pengecualian untuk menangani kondisi yang terjadi secara rutin, dalam beberapa kasus Anda mungkin harus membayar biaya kinerja yang sangat besar. Misalnya, misalkan Anda menjalankan beberapa perintah dari jarak jauh. Anda dapat memeriksa apakah teks perintah Anda melewati setidaknya validasi minimum (mis., Sintaks). Atau Anda bisa menunggu pengecualian muncul (yang terjadi hanya setelah server jauh mem-parsing perintah Anda dan menemukan masalah dengannya). Jelas, yang pertama adalah urutan besarnya lebih cepat. Contoh sederhana lain: Anda dapat memeriksa apakah angka nol ~ 10 kali lebih cepat daripada mencoba menjalankan divisi dan kemudian menangkap pengecualian ZeroDivisionError.

Pertimbangan ini hanya masalah jika Anda sering mengirim string perintah salah ke server jauh atau menerima argumen bernilai nol yang Anda gunakan untuk divisi.

Catatan: Saya berasumsi Anda akan menggunakan except ValueErrorbukan yang adil except; seperti yang ditunjukkan orang lain, dan seperti yang dikatakan buku itu dalam beberapa halaman, Anda tidak boleh menggunakan telanjang except.

Catatan lain: pendekatan non-pengecualian yang tepat adalah menghitung jumlah nilai yang dikembalikan oleh split, alih-alih mencari :. Yang terakhir ini terlalu lambat, karena mengulangi pekerjaan yang dilakukan oleh splitdan mungkin hampir dua kali lipat waktu eksekusi.

maks
sumber
6

Sebagai aturan umum, jika Anda tahu pernyataan dapat menghasilkan hasil yang tidak valid, uji untuk itu dan tangani. Gunakan pengecualian untuk hal-hal yang tidak Anda harapkan; hal-hal yang "luar biasa". Itu membuat kode lebih jelas dalam arti kontrak ("tidak boleh nol" sebagai contoh).

Ian
sumber
2

Gunakan apa yang pernah bekerja dengan baik di ..

  • bahasa pemrograman pilihan Anda dalam hal keterbacaan dan efisiensi kode
  • tim Anda dan set konvensi kode yang disepakati

Baik penanganan pengecualian maupun pemrograman defensif merupakan cara berbeda untuk mengekspresikan maksud yang sama.

Sri
sumber
0

TBH, tidak masalah jika Anda menggunakan try/exceptmekanik atau ifcek pernyataan. Anda biasanya melihat EAFP dan LBYL di sebagian besar baseline Python, dengan EAFP yang sedikit lebih umum. Kadang-kadang EAFP adalah jauh lebih mudah dibaca / idiomatik, tetapi dalam kasus ini saya pikir itu baik-baik saja cara baik.

Namun...

Saya akan berhati-hati menggunakan referensi Anda saat ini. Beberapa masalah mencolok dengan kode mereka:

  1. Deskriptor file bocor. Versi modern dari CPython ( juru bahasa Python tertentu ) akan benar-benar menutupnya, karena ini adalah objek anonim yang hanya ada dalam ruang lingkup selama loop (gc akan nuke setelah loop). Namun, penerjemah lain tidak memiliki jaminan ini. Mereka dapat membocorkan deskriptor secara langsung. Anda hampir selalu ingin menggunakan withidiom saat membaca file dengan Python: ada beberapa pengecualian. Ini bukan salah satunya.
  2. Penanganan pengecualian Pokemon disukai karena topeng kesalahan (yaitu exceptpernyataan telanjang yang tidak menangkap pengecualian tertentu)
  3. Nit: Anda tidak perlu orangtua untuk membongkar tuple. Bisa lakukan sajarole, lineSpoken = eachLine.split(":",1)

Ivc memiliki jawaban yang bagus tentang ini dan EAFP, tetapi juga membocorkan deskriptor.

Versi LBYL tidak harus sama performannya dengan versi EAFP, sehingga mengatakan bahwa melemparkan pengecualian adalah "mahal dalam hal kinerja" adalah pasti salah. Ini benar-benar tergantung pada jenis string yang Anda proses:

In [33]: def lbyl(lines):
    ...:     for line in lines:
    ...:         if line.find(":") != -1:
    ...:             # Nuke the parens, do tuple unpacking like an idiomatic Python dev.
    ...:             role, lineSpoken = line.split(":",1)
    ...:             # no print, since output is obnoxiously long with %timeit
    ...:

In [34]: def eafp(lines):
    ...:     for line in lines:
    ...:         try:
    ...:             # Nuke the parens, do tuple unpacking like an idiomatic Python dev.
    ...:             role, lineSpoken = eachLine.split(":",1)
    ...:             # no print, since output is obnoxiously long with %timeit
    ...:         except:
    ...:             pass
    ...:

In [35]: lines = ["abc:def", "onetwothree", "xyz:hij"]

In [36]: %timeit lbyl(lines)
100000 loops, best of 3: 1.96 µs per loop

In [37]: %timeit eafp(lines)
100000 loops, best of 3: 4.02 µs per loop

In [38]: lines = ["a"*100000 + ":" + "b", "onetwothree", "abconetwothree"*100]

In [39]: %timeit lbyl(lines)
10000 loops, best of 3: 119 µs per loop

In [40]: %timeit eafp(lines)
100000 loops, best of 3: 4.2 µs per loop
Matt Messersmith
sumber
-4

Pada dasarnya penanganan Pengecualian seharusnya lebih sesuai untuk bahasa OOP.

Poin kedua adalah kinerja, karena Anda tidak harus mengeksekusi eachLine.finduntuk setiap baris.

Elalfer
sumber
7
-1: Kinerja adalah alasan yang sangat buruk untuk aturan selimut.
mattnz
3
Tidak, pengecualian sama sekali tidak terkait dengan OOP.
Pubby
-6

Saya pikir pemrograman defensif merusak kinerja. Anda juga harus menangkap hanya pengecualian yang akan Anda tangani, biarkan runtime berurusan dengan pengecualian yang tidak Anda ketahui cara menanganinya.

Manoj
sumber
7
Namun tambahan -1 untuk mencemaskan tentang kinerja lebih dari keterbacaan, maintainablity bla bla bla. Performa bukan alasan.
mattnz
Bolehkah saya tahu mengapa Anda berkeliling membagikan -1 tanpa menjelaskan? Pemrograman defensif berarti lebih banyak baris kode, itu berarti kinerja yang lebih buruk. Adakah yang mau menjelaskan sebelum menembak skor?
Manoj
3
@ Moj: Kecuali Anda telah mengukur dengan profiler dan menemukan blok kode menjadi sangat lambat, kode untuk keterbacaan dan pemeliharaan jauh sebelum kinerja.
Daenyth
Apa yang dikatakan @Manoj dengan penambahan kode yang lebih sedikit secara universal berarti lebih sedikit untuk dikerjakan saat debugging dan pemeliharaan. Hit pada waktu pengembang untuk sesuatu yang kurang dari kode sempurna itu sangat tinggi. Saya berasumsi (seperti saya) Anda tidak menulis kode yang sempurna, maafkan saya jika saya salah.
mattnz
2
Terima kasih untuk tautannya - Menarik dibaca bahwa saya harus setuju dengan hal itu, sampai pada titik ... Bekerja pada sistem yang kritis, seperti yang saya lakukan "Sistem mencetak jejak tumpukan, jadi kami tahu persis mengapa 300 orang itu mati sia-sia. .... "tidak benar-benar akan turun terlalu baik di kursi saksi. Saya kira itu adalah salah satu hal di mana setiap situasi memiliki respons yang sesuai dan berbeda.
mattnz