Apakah ada alasan untuk mewarisi suatu deklarasi kelas object
?
Saya baru saja menemukan beberapa kode yang melakukan ini dan saya tidak dapat menemukan alasan yang bagus mengapa.
class MyClass(object):
# class code follows...
Apakah ada alasan untuk mewarisi suatu deklarasi kelas object
?
Saya baru saja menemukan beberapa kode yang melakukan ini dan saya tidak dapat menemukan alasan yang bagus mengapa.
class MyClass(object):
# class code follows...
Jawaban:
Apakah ada alasan untuk mewarisi suatu deklarasi kelas
object
?
Dalam Python 3, terlepas dari kompatibilitas antara Python 2 dan 3, tidak ada alasan . Dalam Python 2, banyak alasan .
Dalam Python 2.x (dari 2.2 dan seterusnya) ada dua gaya kelas tergantung pada ada atau tidaknya object
sebagai kelas dasar:
kelas gaya "klasik" : mereka tidak memiliki object
sebagai kelas dasar:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
kelas gaya "baru" : mereka memiliki, secara langsung atau tidak langsung (misalnya mewarisi dari tipe bawaan ), object
sebagai kelas dasar:
>>> class NewSpam(object): # directly inherit from object
... pass
>>> NewSpam.__bases__
(<type 'object'>,)
>>> class IntSpam(int): # indirectly inherit from object...
... pass
>>> IntSpam.__bases__
(<type 'int'>,)
>>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object
(<type 'object'>,)
Tanpa ragu, ketika menulis sebuah kelas, Anda selalu ingin mengikuti kelas gaya baru. Manfaat melakukan banyak, untuk daftar beberapa di antaranya:
Dukungan untuk deskriptor . Secara khusus, konstruksi berikut ini dimungkinkan dengan deskriptor:
classmethod
: Metode yang menerima kelas sebagai argumen implisit, bukan contoh.staticmethod
: Metode yang tidak menerima argumen implisit self
sebagai argumen pertama.property
: Membuat fungsi untuk mengelola mendapatkan, menetapkan, dan menghapus atribut.__slots__
: Menghemat konsumsi memori kelas dan juga menghasilkan akses atribut yang lebih cepat. Tentu saja, itu memberlakukan batasan .The __new__
metode statis: memungkinkan Anda menyesuaikan bagaimana baru contoh kelas dibuat.
Metode resolusi urutan (MRO) : dalam urutan apa kelas dasar suatu kelas akan dicari ketika mencoba menyelesaikan metode mana yang akan dipanggil.
Terkait dengan MRO, super
panggilan . Lihat juga, super()
dianggap super.
Jika Anda tidak mewarisi object
, lupakan ini. Deskripsi yang lebih lengkap tentang poin-poin sebelumnya bersama dengan fasilitas kelas gaya "baru" lainnya dapat ditemukan di sini .
Salah satu kelemahan dari kelas gaya baru adalah bahwa kelas itu sendiri lebih menuntut banyak memori. Namun, kecuali jika Anda membuat banyak objek kelas, saya ragu ini akan menjadi masalah dan itu adalah tenggelam negatif di lautan positif.
Dalam Python 3, semuanya disederhanakan. Hanya kelas gaya baru yang ada (disebut sebagai kelas), jadi, satu-satunya perbedaan dalam penambahan object
adalah Anda harus mengetikkan 8 karakter lagi. Ini:
class ClassicSpam:
pass
benar-benar setara (terlepas dari nama mereka :-) dengan ini:
class NewSpam(object):
pass
dan untuk ini:
class Spam():
pass
Semua ada object
di mereka __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
Dalam Python 2: selalu mewarisi dari object
secara eksplisit . Dapatkan fasilitasnya.
Dalam Python 3: mewarisi dari object
jika Anda menulis kode yang mencoba menjadi Python agnostik, yaitu, ia harus bekerja baik dalam Python 2 dan Python 3. Jika tidak, itu tidak ada bedanya karena Python menyisipkannya untuk Anda di balik layar.
object
. IIRC ada titik waktu di mana tidak semua tipe builtin di mana porting ke kelas gaya baru
object
. Saya memiliki Python 2.2.3 di sekitar dan setelah pemeriksaan cepat saya tidak dapat menemukan pelaku tetapi, saya akan menulis ulang jawabannya nanti untuk membuatnya lebih jelas. Akan tertarik jika Anda dapat menemukan contoh, keingintahuan saya terguncang.
object
di pangkalan itu.
staticmethod
dan classmethod
bekerja dengan baik bahkan di kelas gaya lama. property
sorta berfungsi untuk membaca di kelas gaya lama, itu hanya gagal untuk mencegat menulis (jadi jika Anda menetapkan nama, instance mendapatkan atribut dari nama yang diberikan yang membayangi properti). Perhatikan juga bahwa __slots__
peningkatan kecepatan akses atribut sebagian besar adalah tentang kehilangan kerugian yang diakibatkan oleh akses atribut kelas-gaya baru, jadi itu bukan nilai jual kelas-kelas gaya baru (penghematan memori adalah nilai jual).
Python 3
class MyClass(object):
= Kelas gaya baruclass MyClass:
= Kelas gaya baru (secara implisit diturunkan dari object
)Python 2
class MyClass(object):
= Kelas gaya baruclass MyClass:
= KELAS GAYA TUAPenjelasan :
Saat mendefinisikan kelas dasar dalam Python 3.x, Anda diizinkan untuk menghapus object
dari definisi. Namun, ini dapat membuka pintu bagi masalah yang sangat sulit dilacak ...
Python memperkenalkan kelas gaya baru kembali di Python 2.2, dan sekarang kelas gaya lama benar-benar sangat tua. Diskusi kelas gaya lama dimakamkan di dokumen 2.x , dan tidak ada di dokumen 3.x.
Masalahnya adalah, sintaks untuk kelas gaya lama dengan Python 2.x adalah sama dengan sintaks alternatif untuk kelas gaya baru di Python 3.x . Python 2.x masih sangat banyak digunakan (misalnya GAE, Web2Py), dan kode apa pun (atau pembuat kode) tanpa disadari membawa definisi kelas gaya 3.x ke dalam kode 2.x akan berakhir dengan beberapa objek dasar yang sudah usang. Dan karena kelas gaya lama tidak ada di radar siapa pun, mereka kemungkinan tidak akan tahu apa yang menimpa mereka.
Jadi cukup jelaskan dan hemat beberapa pengembang 2.x.
__metaclass__ = type
di bagian atas modul (setelah from __future__ import absolute_import, division, print_function
baris :-)); itu adalah peretas kompatibilitas di Py2 yang membuat semua kelas yang kemudian didefinisikan dalam modul gaya baru secara default, dan di Py3, itu benar-benar diabaikan (hanya variabel global acak yang ada di sekitar), jadi tidak berbahaya.
Ya, ini adalah objek 'gaya baru'. Itu adalah fitur yang diperkenalkan di python2.2.
Objek gaya baru memiliki model objek yang berbeda dengan objek klasik, dan beberapa hal tidak akan berfungsi dengan baik dengan objek gaya lama, misalnya super()
, @property
dan deskriptor. Lihat artikel ini untuk deskripsi yang baik tentang apa kelas gaya baru itu.
Tautan SO untuk deskripsi perbedaan: Apa perbedaan antara gaya lama dan kelas gaya baru di Python?
object
dalam Python 2.
Sejarah dari Learn Python the Hard Way :
Versi asli Python tentang suatu kelas telah rusak dalam banyak hal serius. Pada saat kesalahan ini dikenali itu sudah terlambat, dan mereka harus mendukungnya. Untuk memperbaiki masalah, mereka membutuhkan beberapa gaya "kelas baru" sehingga "kelas lama" akan tetap berfungsi tetapi Anda dapat menggunakan versi baru yang lebih benar.
Mereka memutuskan bahwa mereka akan menggunakan kata "objek", huruf kecil, untuk menjadi "kelas" yang Anda warisi untuk membuat kelas. Ini membingungkan, tetapi sebuah kelas mewarisi dari kelas yang bernama "objek" untuk membuat kelas tetapi itu bukan objek yang benar-benar kelasnya, tetapi jangan lupa untuk mewarisi dari objek.
Juga hanya untuk memberi tahu Anda apa perbedaan antara kelas gaya baru dan kelas gaya lama, kelas gaya baru selalu mewarisi dari object
kelas atau dari kelas lain yang diwarisi dari object
:
class NewStyle(object):
pass
Contoh lain adalah:
class AnotherExampleOfNewStyle(NewStyle):
pass
Sementara kelas dasar gaya lama terlihat seperti ini:
class OldStyle():
pass
Dan kelas anak gaya lama terlihat seperti ini:
class OldStyleSubclass(OldStyle):
pass
Anda dapat melihat bahwa kelas dasar Gaya Lama tidak mewarisi dari kelas lain, namun, kelas Gaya Lama tentu saja dapat mewarisi dari satu sama lain. Mewarisi dari objek menjamin bahwa fungsionalitas tertentu tersedia di setiap kelas Python. Kelas gaya baru diperkenalkan dengan Python 2.2
object
tidak terlalu membingungkan, dan sebenarnya itu cukup standar. Smalltalk memiliki kelas root bernama Object
, dan root metaclass bernama Class
. Mengapa? Karena, seperti Dog
kelas untuk anjing, Object
kelas untuk objek, dan Class
kelas untuk kelas. Java, C #, ObjC, Ruby, dan sebagian besar bahasa OO berbasis kelas lainnya yang digunakan orang saat ini yang memiliki kelas root menggunakan beberapa variasi Object
seperti namanya, bukan hanya Python.
Ya, ini bersejarah . Tanpanya, itu menciptakan kelas gaya lama.
Jika Anda menggunakan type()
objek gaya lama, Anda hanya mendapatkan "instance". Pada objek gaya baru Anda mendapatkan kelasnya.
type()
kelas gaya lama, Anda mendapatkan "classobj" bukannya "ketik".
Sintaks pernyataan penciptaan kelas:
class <ClassName>(superclass):
#code follows
Dengan tidak adanya superclasses lain yang ingin Anda warisi secara khusus, superclass
seharusnya selalu demikian object
, yang merupakan akar dari semua kelas dengan Python.
object
secara teknis akar dari "gaya baru" kelas di Python. Tetapi kelas-kelas gaya baru hari ini sama baiknya dengan menjadi satu-satunya gaya kelas.
Tapi, jika Anda tidak secara eksplisit menggunakan kata object
saat membuat kelas, maka seperti yang disebutkan lainnya, Python 3.x secara implisit mewarisi dari object
superclass. Tapi saya kira eksplisit selalu lebih baik daripada implisit (neraka)