Apakah dianggap sebagai bentuk yang buruk untuk meningkatkan pengecualian di dalam __init__
? Jika demikian, lalu apa metode yang diterima untuk melempar kesalahan ketika variabel kelas tertentu diinisialisasi sebagai None
atau dari tipe yang salah?
128
Jawaban:
Meningkatkan pengecualian di dalam
__init__()
benar-benar baik. Tidak ada cara lain yang baik untuk menunjukkan kondisi kesalahan dalam konstruktor, dan ada banyak contoh di perpustakaan standar tempat membangun objek dapat menimbulkan pengecualian.Kelas kesalahan untuk dinaikkan, tentu saja, terserah Anda.
ValueError
lebih baik jika konstruktor melewati parameter yang tidak valid.sumber
ValueError
danTypeError
.__init__
itu bukan konstruktor, itu intializer. Anda mungkin ingin mengedit baris. Tidak ada cara lain yang baik untuk menunjukkan kondisi kesalahan dalam sebuah konstruktor, ..Memang benar bahwa satu-satunya cara yang tepat untuk menunjukkan kesalahan pada konstruktor adalah dengan meningkatkan pengecualian. Itulah sebabnya dalam C ++ dan dalam bahasa berorientasi objek lainnya yang telah dirancang dengan mempertimbangkan keselamatan pengecualian, destruktor tidak dipanggil jika pengecualian dilemparkan ke dalam konstruktor objek (artinya inisialisasi objek tidak lengkap). Ini sering tidak terjadi dalam bahasa scripting, seperti Python. Misalnya, kode berikut melempar AttributeError jika socket.connect () gagal:
Alasannya adalah bahwa destruktor objek yang tidak lengkap dipanggil setelah upaya koneksi gagal, sebelum atribut stream diinisialisasi. Anda tidak boleh menghindari melemparkan pengecualian dari konstruktor, saya hanya mengatakan bahwa sulit untuk menulis sepenuhnya kode aman dengan Python. Beberapa pengembang Python menghindari penggunaan destruktor sama sekali, tapi itu masalah perdebatan lain.
sumber
__del__
karena kode itu ditulis dengan buruk. Anda akan memiliki masalah yang sama persis jika Anda melakukannyathis->p_socket->close()
dalam destruktor di C ++. Di C ++, Anda tidak akan melakukan itu - Anda akan membiarkan objek anggota menghancurkan dirinya sendiri. Lakukan hal yang sama dengan python.Saya tidak melihat alasan mengapa itu seharusnya bentuk yang buruk.
Sebaliknya, salah satu hal yang dikenal sebagai pengecualian untuk mengembalikan kode kesalahan adalah bahwa kode kesalahan biasanya tidak dapat dikembalikan oleh konstruktor. Jadi setidaknya dalam bahasa seperti C ++, meningkatkan pengecualian adalah satu-satunya cara untuk memberi sinyal kesalahan.
sumber
Perpustakaan standar mengatakan:
Juga saya tidak benar-benar melihat alasan mengapa itu harus dianggap sebagai bentuk yang buruk.
sumber
Saya harus berpikir itu adalah kasus sempurna untuk
ValueError
pengecualian bawaan.sumber
Saya setuju dengan semua hal di atas.
Tidak ada cara lain untuk memberi sinyal bahwa ada yang salah dalam inisialisasi objek selain mengajukan pengecualian.
Di sebagian besar program, kelas di mana keadaan suatu kelas sepenuhnya bergantung pada input ke kelas itu, kita mungkin mengharapkan semacam ValueError atau TypeError untuk dinaikkan.
Kelas dengan efek samping (mis. Yang melakukan jaringan atau grafik) dapat menimbulkan kesalahan init jika (misalnya) perangkat jaringan tidak tersedia atau objek kanvas tidak dapat ditulis. Ini kedengarannya masuk akal bagi saya karena sering Anda ingin tahu tentang kondisi kegagalan sesegera mungkin.
sumber
Membangkitkan kesalahan dari init tidak dapat dihindari dalam beberapa kasus, tetapi melakukan terlalu banyak pekerjaan di init adalah gaya yang buruk. Anda harus mempertimbangkan membuat pabrik atau pseudo-pabrik - metode kelas sederhana yang mengembalikan objek yang diendapkan.
sumber