Dalam Python, saya sering mendengar bahwa lebih baik "meminta maaf" (pengecualian menangkap) daripada "meminta izin" (pemeriksaan jenis / kondisi). Dalam hal menegakkan itik mengetikkan Python, apakah ini
try:
x = foo.bar
except AttributeError:
pass
else:
do(x)
lebih baik atau lebih buruk daripada
if hasattr(foo, "bar"):
do(foo.bar)
else:
pass
dalam hal kinerja, keterbacaan, "pythonic", atau faktor penting lainnya?
exceptions
python
duck-typing
darkfeline
sumber
sumber
hasattr
diterapkan dengan mencoba / menangkap yang tepat secara internal. Tidak yakin apakah itu benar ... (itu akan bertindak berbeda pada properti, bukan? Mungkin saya memikirkangetattr
..)hasattr
tidak menggunakan setara C-APIgetattr
(kembaliTrue
jika berhasil,False
jika tidak), tetapi menangani pengecualian dalam C jauh lebih cepat.Jawaban:
Itu benar-benar tergantung pada seberapa sering Anda berpikir pengecualian akan dilempar.
Kedua pendekatan itu, menurut saya, sama-sama valid, setidaknya dalam hal keterbacaan dan ke-pythonic. Tetapi jika 90% dari objek Anda tidak memiliki atribut
bar
Anda akan melihat perbedaan kinerja yang berbeda antara kedua pendekatan:Tetapi jika 90% dari benda Anda lakukan memiliki atribut, tabel telah berubah:
Jadi, dari sudut pandang kinerja, Anda perlu memilih pendekatan yang paling cocok untuk keadaan Anda.
Pada akhirnya, beberapa penggunaan strategis
timeit
modul mungkin merupakan hal paling Pythonic yang dapat Anda lakukan.sumber
hasattr
, sebenarnya C-api setara dengan coba-kecuali di bawah kap, karena ternyata satu-satunya cara umum untuk menentukan apakah suatu objek memiliki atribut dalam Python adalah dengan mencoba mengaksesnya.Dalam python Anda sering mendapatkan kinerja yang lebih baik dalam melakukan berbagai hal dengan cara Python. Dengan bahasa lain, menggunakan pengecualian untuk kontrol aliran umumnya dianggap sebagai ide yang buruk karena pengecualian biasanya membebankan biaya overhead yang luar biasa. Tetapi karena teknik ini secara eksplisit didukung dalam Python, juru bahasa dioptimalkan untuk jenis kode ini.
Seperti halnya semua pertanyaan kinerja, satu-satunya cara untuk memastikan adalah membuat profil kode Anda. Tulis kedua versi dan lihat mana yang berjalan lebih cepat. Meskipun dalam pengalaman saya, "cara Python" biasanya merupakan cara tercepat.
sumber
Kinerja, saya rasa, adalah masalah sekunder. Jika itu muncul, seorang profiler akan membantu Anda fokus pada kemacetan nyata, yang mungkin atau mungkin bukan cara Anda memperlakukan kemungkinan argumen ilegal.
Di sisi lain, keterbacaan dan kesederhanaan selalu menjadi perhatian utama. Tidak ada aturan keras di sini, cukup gunakan penilaian Anda.
Ini adalah masalah universal, tetapi konvensi khusus lingkungan atau bahasa relevan. Sebagai contoh, dalam Python biasanya baik-baik saja menggunakan atribut yang Anda harapkan dan membiarkan AttributeError yang mungkin menjangkau pemanggil.
sumber
Dalam hal kebenaran , saya pikir penanganan pengecualian adalah cara untuk pergi (saya kadang-kadang menggunakan pendekatan hasattr () sendiri). Masalah mendasar dengan mengandalkan hasattr () adalah ia mengubah pelanggaran kontrak kode menjadi kegagalan diam (ini adalah masalah besar dalam JavaScript, yang tidak membuang properti yang tidak ada).
sumber