Artikel ini membawa anda pengetahuan yang berkaitan tentang python, yang terutamanya memperkenalkan isu berkaitan fungsi "__missing__()" Mari kita lihat fungsi ajaib ini bersama-sama, berharap Semua orang dapat membantu.
Pembelajaran yang disyorkan: Tutorial pembelajaran python
Apabila mendapatkan nilai daripada kamus biasa, kunci mungkin tidak wujud:
dd = {'name':'PythonCat'} dd.get('age') # 结果:None dd.get('age', 18) # 结果:18 dd['age'] # 报错 KeyError dd.__getitem__('age') # 等同于 dd['age']
Untuk kaedah get(), ia mempunyai nilai pulangan Dan parameter kedua boleh dihantar sebagai kandungan pulangan apabila kunci tidak wujud, jadi ia boleh diterima. Walau bagaimanapun, dua kaedah penulisan yang lain akan melaporkan ralat.
Untuk menyelesaikan masalah dua kaedah penulisan yang terakhir, anda boleh menggunakan kaedah sihir __missing__().
Sekarang, katakan kita mempunyai permintaan seperti ini: ambil nilai yang sepadan dengan kunci tertentu dari kamus, kembalikan nilai jika terdapat nilai, masukkan kunci jika tiada nilai, dan berikannya nilai lalai (seperti senarai kosong).
Jika anda menggunakan dict asli, ia tidak mudah untuk dilaksanakan Namun, Python menyediakan kelas sambungan yang sangat mudah digunakancollections.defaultdict
:
Sebagai contoh Seperti yang ditunjukkan dalam rajah, apabila kunci yang tidak wujud diambil, KeyError tidak dilaporkan lagi, tetapi disimpan dalam kamus secara lalai.
Mengapa lalai boleh melakukan ini?
Alasannya ialah defaultdict juga mentakrifkan kaedah __missing__() selepas mewarisi dict jenis terbina dalam Apabila __getitem__ mengambil nilai yang tidak wujud, ia akan memanggil fungsi kilang yang diluluskan dalam parameter input contoh di atas memanggil senarai() untuk membuat senarai kosong).
Sebagai contoh paling tipikal, defaultdict menulis dalam ulasan dokumentasi:
Ringkasnya, fungsi utama __missing__() dipanggil oleh __getitem__ apabila kunci tiada untuk mengelakkan KeyError.
Satu lagi contoh penggunaan biasa ialah collections.Counter
, yang juga merupakan subkelas dict Apabila mengambil kunci yang tidak dikira, kiraan 0 dikembalikan:
__getitem__() tidak semestinya memanggil __missing__() apabila nilai tidak boleh diperolehi.
Ini kerana ia bukan atribut yang diperlukan bagi jenis terbina dalam dan tidak dipratakrifkan dalam kelas asas kamus. Jika anda mengambil nilai atribut terus daripada jenis dict, ia akan dilaporkan bahawa atribut itu tidak wujud:. AttributeError: type object 'object' has no attribute '__missing__'
Ia adalah kaedah yang dilahirkan dalam Sihir kaedah dalam subkelas!
Menurut ini, saya mempunyai tekaan yang tidak matang: __getitem__() akan menentukan sama ada objek semasa ialah subkelas dict dan sama ada ia mempunyai __missing__(), dan kemudian memanggilnya (jika Jika kaedah ini juga wujud dalam kelas induk, ia akan dipanggil terus tanpa membuat pertimbangan terlebih dahulu). Saya menyebut tekaan ini dalam kumpulan komunikasi dan beberapa pelajar dengan cepat menemui pengesahan dalam kod sumber CPython:Dan ini menarik, Kaedah ajaib yang hanya wujud pada subkelas jenis terbina dalam, Melihat seluruh dunia Python, mungkin sukar untuk mencari contoh kedua.
Saya tiba-tiba mendapat idea: __missing__() yang sukar difahami ini seperti ahli silap mata yang pandai "mengubah orang menjadi makhluk hidup". Mula-mula, biarkan penonton melihatnya melalui kaca di luar (iaitu, pegawai Dokumen), bagaimanapun, apabila pintu dibuka, dia tidak berada di dalam (iaitu, jenis terbina dalam Selepas menukar prop, dia kelihatan utuh semula (iaitu, subkelas dict).
__missing__(), sebagai tambahan kepada "sihir"nya sendiri, ia juga memerlukan "sihir" yang kuat "Didorong oleh bakat.
Dalam artikel lepas, saya mendapati bahawa kaedah sihir asli adalah bebas antara satu sama lain Mereka mungkin mempunyai logik teras yang sama dalam antara muka bahasa C, tetapi tiada hubungan panggilan dalam antara muka bahasa Python:
Tingkah laku kaedah sihir "tiada hubungan" ini melanggar prinsip penggunaan semula kod umum, dan juga menyebabkan beberapa kelakuan aneh dalam subkelas jenis sebab terbina dalam.
Piton Rasmi lebih suka menyediakan subkelas UserString, UserList dan UserDict yang baharu daripada menggunakan semula kaedah sihir Satu-satunya penjelasan yang munasabah nampaknya kos membuat kaedah sihir memanggil satu sama lain adalah terlalu tinggi.
Walau bagaimanapun, untuk kes khas __missing__(), Python perlu berkompromi dan membayar harga ini!
__missing__() ialah "warganegara kelas kedua" kaedah sihir Ia tidak mempunyai pintu masuk panggilan bebas dan hanya boleh dipanggil secara pasif oleh __getitem__(), iaitu, __missing__() bergantung pada __getitem__().
berbeza daripada "Warganegara kelas pertama", seperti __init__(), __enter__(), __len__(), __eq__(), dsb., mereka sama ada dalam objek kitaran hayat atau pelaksanaan Nod tertentu dalam proses dicetuskan, atau dicetuskan oleh fungsi atau pengendali terbina dalam Ini adalah peristiwa yang agak bebas dan tidak mempunyai kebergantungan.
__missing__() bergantung pada __getitem__() untuk mencapai kaedah panggilan; dan __getitem__() juga bergantung pada __missing__() untuk mencapai kefungsian lengkap.
Untuk mencapai ini, __getitem__() membuka pintu belakang dalam kod penterjemah, kembali daripada antara muka bahasa C ke antara muka Python untuk memanggil kaedah khusus bernama "__missing__".
Dan inilah "sihir" sebenar setakat ini, __missing__() nampaknya satu-satunya kaedah sihir yang menikmati rawatan sedemikian!
Kamus Python menyediakan dua kaedah terbina dalam untuk mendapatkan nilai, iaitu __getitem__() dan get( Apabila nilai itu tidak wujud, strategi pemprosesannya adalah Berbeza: Yang pertama akan melaporkan ralatKeyError
, manakala yang kedua akan mengembalikan Tiada.
Mengapa Python menyediakan dua kaedah berbeza? Atau anda harus bertanya, mengapa Python mengendalikan kedua-dua kaedah ini secara berbeza?
Ini mungkin mempunyai penjelasan yang sangat rumit (atau sangat mudah), yang tidak akan saya teliti dalam artikel ini.
Tetapi satu perkara yang pasti: iaitu kaedah melontar yang mudah dan kasar KeyError
daripada jenis dict asli tidak mencukupi.
Untuk memberikan jenis kamus prestasi yang lebih berkuasa (atau biarkan __getitem__() berkelakuan seperti get()), Python membenarkan subkelas kamus untuk mentakrifkan __missing__() untuk __getitem__() Cari panggilan.
Artikel ini menyusun prinsip pelaksanaan __missing__(), mendedahkan bahawa ia bukanlah kewujudan yang tidak mencolok Sebaliknya, ia adalah satu-satunya yang memecahkan halangan antara kaedah sihir dan menyokong sihir lain. kes khas panggilan kaedah ajaib!
Untuk mengekalkan kebebasan kaedah sihir, Python bersusah payah untuk memperkenalkan kelas terbitan seperti UserString, UserList dan UserDict, tetapi untuk __missing__(), ia memilih untuk berkompromi.
Pembelajaran yang disyorkan: tutorial python
Atas ialah kandungan terperinci Pembelajaran fungsi sihir Python __hilang__. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!