Saya memiliki kelas Python, yang saya hanya perlu satu contoh pada waktu proses, jadi itu akan cukup untuk memiliki atribut hanya sekali per kelas dan bukan per contoh. Jika akan ada lebih dari satu instance (yang tidak akan terjadi), semua instance harus memiliki konfigurasi yang sama. Saya ingin tahu opsi mana yang lebih baik atau lebih "idiomatis" Python.
Variabel kelas:
class MyController(Controller):
path = "something/"
children = [AController, BController]
def action(self, request):
pass
Variabel instance:
class MyController(Controller):
def __init__(self):
self.path = "something/"
self.children = [AController, BController]
def action(self, request):
pass
Jawaban:
Jika Anda hanya memiliki satu instance, yang terbaik adalah membuat semua variabel per instance, hanya karena mereka akan diakses (sedikit) lebih cepat (satu level "pencarian" lebih sedikit karena "inheritance" dari kelas ke instance), dan tidak ada kerugian untuk menimbang keuntungan kecil ini.
sumber
python -mtimeit
- tetapi baru saja melakukannya di python3.4 Saya perhatikan bahwa mengaksesint
variabel kelas sebenarnya sekitar 5 hingga 11 nanodetik lebih cepat daripada variabel instan di workstation lama saya - tidak yakin apa codepath membuatnya begitu.Lebih lanjut menggemakan saran Mike dan Alex dan menambahkan warna saya sendiri ...
Menggunakan atribut instance adalah tipikal ... Python yang lebih idiomatis. Atribut kelas tidak terlalu sering digunakan, karena kasus penggunaannya bersifat spesifik. Hal yang sama juga berlaku untuk metode statis dan kelas vs. metode "normal". Mereka adalah konstruksi khusus yang menangani kasus penggunaan tertentu, jika tidak, kode itu dibuat oleh programmer yang menyimpang yang ingin menunjukkan bahwa mereka tahu beberapa sudut yang tidak jelas dari pemrograman Python.
Alex menyebutkan dalam balasannya bahwa akses akan (sedikit) lebih cepat karena satu tingkat pencarian yang lebih sedikit ... izinkan saya menjelaskan lebih lanjut bagi mereka yang belum tahu tentang cara kerjanya. Ini sangat mirip dengan akses variabel - urutan pencariannya adalah:
Untuk akses atribut, urutannya adalah:
Kedua teknik bekerja secara "inside-out", yang berarti sebagian besar objek lokal diperiksa terlebih dahulu, kemudian lapisan luar diperiksa secara berurutan.
Dalam contoh Anda di atas, misalkan Anda mencari
path
atribut. Ketika menemukan referensi seperti "self.path
", Python akan melihat atribut instance terlebih dahulu untuk kecocokan. Ketika gagal, itu memeriksa kelas dari mana objek itu dibuat. Akhirnya, itu akan mencari kelas dasar. Seperti yang dikatakan Alex, jika atribut Anda ditemukan dalam instans, atribut tersebut tidak perlu mencari di tempat lain, sehingga menghemat sedikit waktu Anda.Namun, jika Anda bersikeras menggunakan atribut kelas, Anda memerlukan pencarian ekstra tersebut. Atau , alternatif Anda yang lain adalah merujuk ke objek melalui kelas alih-alih instance, misalnya,
MyController.path
alih-alihself.path
. Itu adalah pencarian langsung yang akan mengatasi pencarian yang ditangguhkan, tetapi seperti yang disebutkan alex di bawah ini, ini adalah variabel global, jadi Anda kehilangan sedikit yang Anda pikir akan disimpan (kecuali jika Anda membuat referensi lokal ke nama kelas [global] ).Intinya adalah Anda harus menggunakan atribut instance hampir sepanjang waktu. Namun, ada kalanya atribut kelas adalah alat yang tepat untuk pekerjaan itu. Kode yang menggunakan keduanya pada saat yang sama akan membutuhkan ketekunan yang paling tinggi, karena menggunakan
self
hanya akan memberi Anda objek atribut instance dan akses bayangan ke atribut kelas dengan nama yang sama. Dalam kasus ini, Anda harus menggunakan akses atribut dengan nama kelas untuk mereferensikannya.sumber
MyController
yang mendongak di GLOBALS, sehingga total biaya lebih tinggi dariself.path
manapath
adalah variabel instansi (karenaself
merupakan daerah dengan metode == super cepat lookup).Jika ragu, Anda mungkin menginginkan atribut instance.
Atribut kelas paling baik disediakan untuk kasus-kasus khusus yang masuk akal. Satu-satunya kasus penggunaan yang sangat umum adalah metode. Tidak jarang menggunakan atribut kelas untuk konstanta hanya-baca yang perlu diketahui instance (meskipun satu-satunya manfaat ini adalah jika Anda juga menginginkan akses dari luar kelas), tetapi Anda harus berhati-hati dalam menyimpan status apa pun di dalamnya , yang jarang Anda inginkan. Bahkan jika Anda hanya akan memiliki satu contoh, Anda harus menulis kelas seperti yang Anda lakukan pada yang lain, yang biasanya berarti menggunakan atribut contoh.
sumber
avoid global variables
dan definisinya adalah, bahwa variabel global juga variabel yang dideklarasikan sebagai atribut kelas. Namun, panduan gaya Python sendiri ( PEP-8 ) harus menjadi tempat pertama untuk menjawab pertanyaan semacam ini. Maka pikiran Anda sendiri harus menjadi alat pilihan (tentu saja Anda juga bisa mendapatkan ide dari Google, misalnya).Pertanyaan yang sama di Performa mengakses variabel kelas dengan Python - kode di sini diadaptasi dari @Edward Loper
Variabel Lokal adalah yang tercepat untuk diakses, cukup terikat dengan Variabel Modul, diikuti oleh Variabel Kelas, diikuti oleh Variabel Instans.
Ada 4 cakupan variabel yang dapat Anda akses:
Ujian:
Hasil:
sumber