Saya memiliki kelas yang hanya berisi bidang dan tidak ada metode, seperti ini:
class Request(object):
def __init__(self, environ):
self.environ = environ
self.request_method = environ.get('REQUEST_METHOD', None)
self.url_scheme = environ.get('wsgi.url_scheme', None)
self.request_uri = wsgiref.util.request_uri(environ)
self.path = environ.get('PATH_INFO', None)
# ...
Ini dapat dengan mudah diterjemahkan menjadi dikt. Kelas lebih fleksibel untuk penambahan di masa mendatang dan dapat digunakan dengan cepat __slots__
. Jadi, apakah ada manfaatnya menggunakan dict? Akankah sebuah dict lebih cepat dari sebuah kelas? Dan lebih cepat dari kelas dengan slot?
python
oop
class
dictionary
deamon
sumber
sumber
dict
bisa masuk akal, hingga. keuntungan rapi: ketika Anda men-debug, katakan sajaprint(request)
dan Anda akan segera melihat semua informasi status. dengan pendekatan yang lebih klasik Anda harus menulis__str__
metode kustom Anda , yang menyebalkan jika Anda harus melakukannya sepanjang waktu.Jawaban:
Mengapa Anda menjadikan ini kamus? Apa keuntungannya? Apa yang terjadi jika nanti Anda ingin menambahkan beberapa kode? Kemana
__init__
kode Anda akan pergi?Kelas untuk menggabungkan data terkait (dan biasanya kode).
Kamus digunakan untuk menyimpan hubungan nilai-kunci, di mana biasanya semua kunci memiliki tipe yang sama, dan semua nilai juga merupakan satu jenis. Terkadang mereka dapat berguna untuk menggabungkan data ketika nama kunci / atribut tidak semuanya diketahui sebelumnya, tetapi seringkali ini merupakan tanda bahwa ada sesuatu yang salah dengan desain Anda.
Pertahankan ini sebagai kelas.
sumber
__init__
. Tapi Anda benar: Saya akan memisahkan hal-hal yang menjadi milik bersama.where would your __init__ code go?
sangat memprihatinkan. Itu bisa meyakinkan pengembang yang kurang berpengalaman bahwa hanya kelas yang akan digunakan karena metode init tidak digunakan dalam kamus. Konyol.Gunakan kamus kecuali Anda membutuhkan mekanisme ekstra dari sebuah kelas. Anda juga bisa menggunakan
namedtuple
untuk pendekatan hybrid:Perbedaan kinerja di sini akan minimal, meskipun saya akan terkejut jika kamus tidak lebih cepat.
sumber
Kelas dengan python adalah dikt di bawahnya. Anda memang mendapatkan beberapa overhead dengan perilaku kelas, tetapi Anda tidak akan dapat menyadarinya tanpa profiler. Dalam hal ini, saya yakin Anda mendapat manfaat dari kelas karena:
sumber
Saya pikir penggunaan masing-masing terlalu subyektif bagi saya untuk memahaminya, jadi saya akan tetap berpegang pada angka.
Saya membandingkan waktu yang dibutuhkan untuk membuat dan mengubah variabel dalam sebuah dict, kelas gaya_baru dan kelas gaya_baru dengan slot.
Inilah kode yang saya gunakan untuk mengujinya (agak berantakan tetapi berhasil.)
Dan inilah hasilnya ...
Membuat ...
Mengubah variabel ...
Jadi, jika Anda hanya menyimpan variabel, Anda memerlukan kecepatan, dan tidak mengharuskan Anda melakukan banyak perhitungan, saya sarankan menggunakan dict (Anda selalu bisa membuat fungsi yang terlihat seperti metode). Tetapi, jika Anda benar-benar membutuhkan kelas, ingat - selalu gunakan __ slot __ .
catatan:
Saya menguji 'Kelas' dengan kelas gaya_baru dan gaya_baru. Ternyata kelas old_style lebih cepat dibuat tetapi lebih lambat untuk dimodifikasi (tidak terlalu signifikan tetapi signifikan jika Anda membuat banyak kelas dalam putaran yang ketat (tip: Anda salah melakukannya)).
Juga waktu untuk membuat dan mengubah variabel mungkin berbeda di komputer Anda karena milik saya sudah tua dan lambat. Pastikan Anda mengujinya sendiri untuk melihat hasil 'nyata'.
Edit:
Saya kemudian menguji nametuple: saya tidak dapat memodifikasinya tetapi untuk membuat 10.000 sampel (atau sesuatu seperti itu) butuh 1,4 detik sehingga kamus memang yang tercepat.
Jika saya mengubah fungsi dict untuk memasukkan kunci dan nilai dan mengembalikan dict alih-alih variabel yang berisi dict ketika saya membuatnya, itu memberi saya 0,65 daripada 0,8 detik.
Membuat seperti kelas dengan slot dan mengubah variabel paling lambat (0,17 detik) jadi jangan gunakan kelas ini . gunakan dict (kecepatan) atau untuk kelas yang diturunkan dari objek ('syntax candy')
sumber
dict
(tanpa metode yang diganti, saya kira?). Apakah itu bekerja dengan cara yang sama seperti kelas gaya baru yang ditulis dari awal?Saya setuju dengan @adw. Saya tidak akan pernah mewakili sebuah "objek" (dalam arti OO) dengan kamus. Kamus menggabungkan pasangan nama / nilai. Kelas mewakili objek. Saya telah melihat kode di mana objek diwakili dengan kamus dan tidak jelas apa bentuk sebenarnya dari benda itu. Apa yang terjadi jika nama / nilai tertentu tidak ada? Apa yang membatasi klien untuk memasukkan apa pun ke dalam. Atau mencoba mengeluarkan apa pun. Bentuk benda harus selalu didefinisikan dengan jelas.
Saat menggunakan Python, penting untuk membangun dengan disiplin karena bahasanya memungkinkan banyak cara bagi penulis untuk menembak dirinya sendiri.
sumber
Saya akan merekomendasikan kelas, karena semua jenis informasi yang terlibat dengan permintaan. Jika seseorang menggunakan kamus, saya berharap data yang disimpan jauh lebih mirip di alam. Sebuah pedoman yang cenderung saya ikuti sendiri adalah bahwa jika saya ingin mengulang seluruh rangkaian pasangan kunci-> nilai dan melakukan sesuatu, saya menggunakan kamus. Jika tidak, data tampaknya memiliki struktur yang jauh lebih banyak daripada pemetaan nilai kunci-> dasar, yang berarti kelas kemungkinan akan menjadi alternatif yang lebih baik.
Oleh karena itu, tetaplah dengan kelas.
sumber
Jika semua yang Anda ingin kita wajib adalah sintaks permen seperti
obj.bla = 5
bukanobj['bla'] = 5
, terutama jika Anda harus mengulangi bahwa banyak, Anda mungkin ingin menggunakan beberapa kelas wadah polos seperti di martineaus saran. Namun demikian, kode di sana cukup membengkak dan terlalu lambat. Anda bisa membuatnya sederhana seperti itu:Alasan lain untuk beralih ke
namedtuple
s atau kelas dengan__slots__
mungkin penggunaan memori. Diktik membutuhkan lebih banyak memori daripada jenis daftar, jadi ini bisa menjadi poin untuk dipikirkan.Bagaimanapun, dalam kasus khusus Anda, tampaknya tidak ada motivasi untuk beralih dari penerapan Anda saat ini. Anda tampaknya tidak mempertahankan jutaan objek ini, jadi tidak diperlukan tipe turunan daftar. Dan itu sebenarnya mengandung beberapa logika fungsional di dalam
__init__
, jadi Anda juga tidak boleh mendapatkannyaAttrDict
.sumber
types.SimpleNamespace
(tersedia sejak Python 3.3) adalah alternatif dari AttrDict kustom.Dimungkinkan untuk memiliki kue Anda dan memakannya juga. Dengan kata lain, Anda dapat membuat sesuatu yang menyediakan fungsionalitas instance kelas dan kamus. Lihat resep Dɪᴄᴛɪᴏɴᴀʀʏ ᴡɪᴛʜ ᴀᴛᴛʀɪʙᴜᴛᴇ-sᴛʏʟᴇ ᴀᴄᴄᴇss ActiveState dan komentar tentang cara melakukannya.
Jika Anda memutuskan untuk menggunakan kelas biasa daripada subkelas, saya telah menemukan resep Tʜᴇ sɪᴍᴘʟᴇ ʙᴜᴛ ʜᴀɴᴅʏ "ᴄᴏʟʟᴇᴄᴛᴏʀ ᴏғ ᴀ ʙᴜɴᴄʜ ᴏғ ɴᴀᴍᴇᴅ sᴛᴜғғ" ᴄʟᴀss (oleh Alex Martelli) sangat fleksibel dan berguna untuk hal-hal yang berkaitan dengan itu. seperti yang Anda lakukan (yaitu membuat agregator informasi yang relatif sederhana). Karena ini adalah kelas, Anda dapat dengan mudah memperluas fungsinya lebih jauh dengan menambahkan metode.
Terakhir, perlu dicatat bahwa nama anggota kelas harus merupakan pengenal resmi Python, tetapi kunci kamus tidak demikian — jadi kamus akan memberikan kebebasan yang lebih besar dalam hal itu karena kunci dapat berupa apa saja yang dapat di-hash (bahkan sesuatu yang bukan string).
Memperbarui
Sebuah kelas
object
(yang tidak memiliki__dict__
) subkelas bernamaSimpleNamespace
(yang memang memilikinya) telah ditambahkan ketypes
modul Python 3.3, dan merupakan alternatif lain.sumber
Saya merekomendasikan kelas. Jika Anda menggunakan kelas, Anda bisa mendapatkan petunjuk tipe seperti yang ditunjukkan. Dan Kelas mendukung pelengkapan otomatis ketika kelas adalah argumen fungsi.
sumber