Apa perbedaan antara kelas gaya lama dan gaya baru di Python? Kapan saya harus menggunakan yang satu atau yang lain?
Dari kelas baru dan klasik :
Hingga Python 2.1, kelas gaya lama adalah satu-satunya rasa yang tersedia bagi pengguna.
Konsep kelas (gaya lama) tidak terkait dengan konsep tipe: jika
x
adalah turunan dari kelas gaya lama, maka kelas tersebut akanx.__class__
ditunjukx
, tetapitype(x)
selalu<type 'instance'>
.Ini mencerminkan fakta bahwa semua instance gaya lama, terlepas dari kelasnya, diimplementasikan dengan tipe built-in tunggal, yang disebut instance.
Kelas-kelas gaya baru diperkenalkan dalam Python 2.2 untuk menyatukan konsep kelas dan tipe . Kelas gaya baru hanyalah tipe yang ditentukan pengguna, tidak lebih, tidak kurang.
Jika x adalah turunan dari kelas gaya baru, maka
type(x)
biasanya sama denganx.__class__
(meskipun ini tidak dijamin - turunan kelas gaya baru diizinkan untuk mengesampingkan nilai yang dikembalikan untukx.__class__
).Motivasi utama untuk memperkenalkan kelas gaya baru adalah untuk menyediakan model objek terpadu dengan meta-model penuh .
Ini juga memiliki sejumlah manfaat langsung, seperti kemampuan untuk mensubklasifikasikan sebagian besar tipe bawaan, atau pengenalan "deskriptor", yang memungkinkan properti yang dihitung.
Untuk alasan kompatibilitas, kelas secara default masih bergaya lama .
Kelas gaya baru dibuat dengan menentukan kelas gaya baru lainnya (yaitu tipe) sebagai kelas induk, atau objek "tipe tingkat atas" jika tidak diperlukan induk lain.
Perilaku kelas gaya baru berbeda dari kelas gaya lama dalam sejumlah detail penting selain jenis apa yang dikembalikan.
Beberapa perubahan ini sangat mendasar bagi model objek baru, seperti cara metode khusus dipanggil. Lainnya adalah "perbaikan" yang tidak dapat diimplementasikan sebelumnya karena masalah kompatibilitas, seperti urutan resolusi metode dalam hal pewarisan berganda.
Python 3 hanya memiliki kelas gaya baru .
Tidak masalah apakah Anda subkelas dari
object
atau tidak, kelas adalah gaya baru di Python 3.
type(x)
. Jika saya tidak mensubklasifikasikan tipe bawaan, maka sepertinya tidak ada keuntungan yang bisa saya lihat dari kelas-kelas gaya baru. Ada kelemahan, yaitu mengetik ekstra(object)
.super()
tidak berfungsi pada kelas gaya lama. Belum lagi, seperti kata artikel itu, ada perbaikan mendasar, seperti MRO, dan metode khusus, yang lebih dari alasan yang baik untuk menggunakannya.Dari segi deklarasi:
Kelas gaya baru mewarisi dari objek , atau dari kelas gaya baru lainnya.
Kelas gaya lama tidak.
Python 3 Catatan:
Python 3 tidak mendukung kelas gaya lama, jadi bentuk apa pun yang disebutkan di atas menghasilkan kelas gaya baru.
sumber
object
.class AnotherOldStyleClass: pass
class A: pass
danclass A(): pass
sangat setara. Yang pertama berarti "A tidak mewarisi kelas induk mana pun" dan yang kedua berarti "A warisan dari kelas induk tidak" . Itu sangat mirip dengannot is
danis not
Perubahan perilaku penting antara kelas gaya lama dan baru
Exception
(contoh di bawah)__slots__
ditambahkanMRO (Urutan Resolusi Metode) berubah
Itu disebutkan dalam jawaban lain, tetapi inilah contoh konkret dari perbedaan antara MRO klasik dan C3 MRO (digunakan dalam kelas gaya baru).
Pertanyaannya adalah urutan di mana atribut (yang mencakup metode dan variabel anggota) dicari dalam beberapa pewarisan.
Kelas klasik melakukan pencarian mendalam-pertama dari kiri ke kanan. Berhenti pada pertandingan pertama. Mereka tidak memiliki
__mro__
atribut.Kelas-kelas gaya baru MRO lebih rumit untuk disintesis dalam satu kalimat bahasa Inggris. Dijelaskan secara rinci di sini . Salah satu propertinya adalah bahwa kelas dasar hanya dicari setelah semua kelas turunannya telah. Mereka memiliki
__mro__
atribut yang menunjukkan urutan pencarian.Objek kelas gaya baru tidak dapat dinaikkan kecuali berasal dari
Exception
Sekitar Python 2.5 banyak kelas bisa dinaikkan, dan sekitar Python 2.6 ini dihapus. Pada Python 2.7.3:
sumber
Kelas gaya lama masih sedikit lebih cepat untuk pencarian atribut. Ini biasanya tidak penting, tetapi mungkin berguna dalam kode Python 2.x yang peka terhadap kinerja:
sumber
%timeit aobj.a
10000000 loops, best of 3: 66.1 ns per loop
%timeit bobj.a
10000000 loops, best of 3: 53.9 ns per loop
Guido telah menulis The Inside Story di New-Style Classes , sebuah artikel yang sangat bagus tentang kelas gaya baru dan gaya lama dengan Python.
Python 3 hanya memiliki kelas gaya baru. Bahkan jika Anda menulis 'kelas gaya lama', itu secara implisit berasal dari
object
.Kelas-kelas gaya baru memiliki beberapa fitur lanjutan yang kurang di kelas-kelas gaya lama, seperti
super
, mro C3 baru , beberapa metode magis, dll.sumber
Inilah perbedaan yang sangat praktis, benar / salah. Satu-satunya perbedaan antara dua versi kode berikut adalah bahwa dalam versi kedua, Orang mewarisi dari objek . Selain itu, kedua versi itu identik, tetapi dengan hasil yang berbeda:
Kelas gaya lama
Kelas gaya baru
sumber
_names_cache
adalah kamus yang menyimpan (menyimpan untuk pengambilan di masa depan) setiap nama yang Anda berikanPerson.__new__
. Metode setdefault (didefinisikan dalam kamus apa pun) membutuhkan dua argumen: kunci dan nilai. Jika kunci ada dalam dikt, ia akan mengembalikan nilainya. Jika tidak ada dict, itu akan mengaturnya terlebih dahulu ke nilai yang diteruskan sebagai argumen kedua dan kemudian mengembalikannya.__new__()
selalu dipanggil, dan selalu membangun objek baru, lalu melemparkannya. Dalam hal ini aif
lebih disukai daripada.setdefault()
.__new__
sebenarnya bukan sesuatu untuk kelas gaya lama, itu tidak digunakan dalam konstruksi contoh (itu hanya nama acak yang terlihat istimewa, seperti mendefinisikan__spam__
). Jadi membangun kelas gaya lama hanya memanggil__init__
, sedangkan konstruksi gaya baru memanggil__new__
(menyatu dengan singleton misalnya dengan nama) untuk membangun, dan__init__
menginisialisasi.Kelas-kelas gaya baru mewarisi dari
object
dan harus ditulis seperti itu di Python 2.2 dan seterusnya (yaituclass Classname(object):
bukannyaclass Classname:
). Perubahan inti adalah menyatukan jenis dan kelas, dan efek samping yang bagus dari ini adalah memungkinkan Anda mewarisi dari tipe bawaan.Baca descrintro untuk lebih jelasnya.
sumber
Kelas gaya baru dapat menggunakan di
super(Foo, self)
manaFoo
kelas danself
contohnya.Dan dengan Python 3.x Anda cukup menggunakan
super()
di dalam kelas tanpa parameter apa pun.sumber