Sementara saya suka menganggap diri saya sebagai pembuat kode Python yang cukup kompeten, salah satu aspek dari bahasa yang saya tidak pernah bisa grok adalah dekorator.
Saya tahu apa itu (secara dangkal), saya sudah membaca tutorial, contoh, pertanyaan tentang Stack Overflow, dan saya mengerti sintaksnya, bisa menulis sendiri, kadang-kadang menggunakan @classmethod dan @staticmethod, tetapi tidak pernah terpikir oleh saya untuk menggunakan dekorator untuk memecahkan masalah dalam kode Python saya sendiri. Saya tidak pernah menemukan masalah di mana saya berpikir, "Hmm ... ini terlihat seperti pekerjaan untuk dekorator!"
Jadi, saya bertanya-tanya apakah kalian mungkin menawarkan beberapa contoh di mana Anda telah menggunakan dekorator dalam program Anda sendiri, dan mudah-mudahan saya akan memiliki "A-ha!" saat dan mendapatkannya .
functools.lru_cache
,, yang melakukan persis apa yang Peter katakan, sejak Python 3.2, dirilis pada Februari 2011.Jawaban:
Saya menggunakan dekorator terutama untuk tujuan pengaturan waktu
sumber
time.clock()
mengukur waktu CPU. Anda mungkin ingin menggunakannyatime.time()
sebagai gantinya jika Anda ingin mengukur waktu jam dinding.myFunction
menjalankan ...Saya telah menggunakannya untuk sinkronisasi.
Seperti yang ditunjukkan dalam komentar, karena Python 2.5 Anda dapat menggunakan
with
pernyataan bersamaan dengan objekthreading.Lock
(ataumultiprocessing.Lock
sejak versi 2.6) untuk menyederhanakan implementasi dekorator menjadi hanya:Apapun, Anda kemudian menggunakannya seperti ini:
Pada dasarnya itu hanya menempatkan
lock.acquire()
/lock.release()
di kedua sisi panggilan fungsi.sumber
Saya menggunakan dekorator untuk memeriksa parameter yang diteruskan ke metode Python saya melalui beberapa RMI. Jadi alih-alih mengulangi penghitungan parameter yang sama, pengecualian-meningkatkan mumbo-jumbo lagi dan lagi.
Misalnya, alih-alih:
Saya hanya menyatakan:
dan
accepts()
melakukan semua pekerjaan untuk saya.sumber
@accepts
di PEP 318.isinstance()
fungsi bawaan, seperti yang dilakukan dalam implementasi dekorator PEP 318 . Karenaclassinfo
argumennya dapat berupa satu atau lebih jenis, menggunakannya juga akan mengurangi keberatan (Gust) @ Gustavo6046. Python juga memilikiNumber
kelas dasar abstrak, jadi tes yang sangat umum sepertiisinstance(42, numbers.Number)
mungkin dilakukan.Dekorator digunakan untuk apa pun yang Anda ingin "bungkus" transparan dengan fungsionalitas tambahan.
Django menggunakannya untuk membungkus fungsionalitas "diperlukan masuk" pada fungsi tampilan , serta untuk mendaftarkan fungsi filter .
Anda bisa menggunakan dekorator kelas untuk menambahkan log bernama ke kelas .
Fungsionalitas generik apa pun yang dapat Anda "tempel" ke kelas yang ada atau perilaku fungsi adalah permainan yang adil untuk dekorasi.
Ada juga diskusi tentang kasus penggunaan pada newsgroup Python-Dev yang ditunjuk oleh PEP 318 - Dekorator untuk Fungsi dan Metode .
sumber
Untuk ujian ulang, Anda dapat menulis dekorator yang memasok fungsi atau metode uji unit dengan beberapa set parameter:
sumber
Perpustakaan Twisted menggunakan dekorator yang dikombinasikan dengan generator untuk memberikan ilusi bahwa fungsi asinkron bersifat sinkron. Sebagai contoh:
Dengan menggunakan ini, kode yang akan dipecah menjadi satu ton fungsi callback kecil dapat ditulis secara alami sebagai satu blok, sehingga jauh lebih mudah untuk dipahami dan dipelihara.
sumber
Satu penggunaan yang jelas adalah untuk logging, tentu saja:
sumber
Saya menggunakannya terutama untuk debugging (membungkus fungsi yang mencetak argumen dan hasilnya) dan verifikasi (misalnya untuk memeriksa apakah argumen adalah tipe yang benar atau, dalam kasus aplikasi web, jika pengguna memiliki hak yang cukup untuk memanggil tertentu metode).
sumber
Saya menggunakan dekorator berikut untuk membuat fungsi threadsafe. Itu membuat kode lebih mudah dibaca. Ini hampir mirip dengan yang diusulkan oleh John Fouhy tetapi perbedaannya adalah bahwa seseorang bekerja pada fungsi tunggal dan bahwa tidak perlu membuat objek kunci secara eksplisit.
sumber
Dekorator digunakan untuk mendefinisikan properti fungsi atau sebagai pelat yang mengubahnya; itu mungkin tetapi kontra-intuitif bagi mereka untuk mengembalikan fungsi yang sama sekali berbeda. Melihat respons lain di sini, sepertinya salah satu kegunaan yang paling umum adalah membatasi ruang lingkup beberapa proses lainnya - baik itu pencatatan, profil, pemeriksaan keamanan, dll.
CherryPy menggunakan pengiriman objek untuk mencocokkan URL dengan objek dan, akhirnya, metode. Dekorator pada metode-metode tersebut memberi sinyal apakah CherryPy bahkan diperbolehkan menggunakan metode tersebut. Misalnya, diadaptasi dari tutorial :
sumber
Saya menggunakannya baru-baru ini, ketika bekerja pada aplikasi web jejaring sosial. Untuk Komunitas / Grup, saya seharusnya memberikan otorisasi keanggotaan untuk membuat diskusi baru dan membalas pesan Anda harus menjadi anggota grup tersebut. Jadi, saya menulis dekorator
@membership_required
dan meletakkannya di tempat yang saya inginkan dalam pandangan saya.sumber
Saya menggunakan dekorator ini untuk memperbaiki parameter
ini ditulis ketika saya refactor beberapa fungsi perlu melewati argumen "ingin" tetapi dalam kode lama saya, saya melewati N atau 'N' saja
sumber
Dekorator dapat digunakan untuk dengan mudah membuat variabel metode fungsi.
sumber