Pertanyaan Kelas Python mewarisi objek


Apakah ada alasan untuk deklarasi kelas mewarisi dari object?

Saya baru saja menemukan beberapa kode yang melakukan ini dan saya tidak dapat menemukan alasan yang baik mengapa.

class MyClass(object):
    # class code follows...

752
2017-10-25 14:15


asal


Jawaban:


Apakah ada alasan untuk deklarasi kelas mewarisi dari object?

tl; dr: Dalam Python 3, terlepas dari kompatibilitas antara Python 2 dan 3, tak ada alasan. Dengan Python 2, banyak alasan.


Cerita Python 2.x:

Dalam Python 2.x (dari 2.2 dan seterusnya) ada dua gaya kelas tergantung pada ada tidaknya object sebagai kelas dasar:

  1. gaya "klasik" kelas: mereka tidak punya object sebagai kelas dasar:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. "gaya baru kelas: mereka, secara langsung atau tidak langsung (mis. 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 kelas Anda akan selalu ingin pergi untuk kelas gaya baru. Manfaatnya sangat banyak, untuk membuat daftar beberapa di antaranya:

  • Dukungan untuk pendeskripsi. Secara khusus, konstruk berikut dimungkinkan dengan deskriptor:

    1. classmethod: Metode yang menerima kelas sebagai argumen implisit, bukan instance.
    2. staticmethod: Suatu metode yang tidak menerima argumen implisit self sebagai argumen pertama.
    3. properti dengan property: Buat fungsi untuk mengelola perolehan, pengaturan, dan penghapusan atribut.
    4. __slots__: Menghemat konsumsi memori suatu kelas dan juga menghasilkan akses atribut yang lebih cepat. Tentu saja memberlakukan batasan.
  • Itu __new__ metode statis: memungkinkan Anda menyesuaikan cara instance kelas baru dibuat.

  • Perintah resolusi metode (MRO): dalam urutan apa kelas dasar suatu kelas akan dicari ketika mencoba untuk menyelesaikan metode mana yang harus dihubungi.

  • Terkait dengan MRO, super panggilan. Lihat juga, super() dianggap super.

Jika Anda tidak mewarisi dari object, lupakan ini. Deskripsi yang lebih lengkap tentang poin-poin peluru sebelumnya bersama dengan manfaat lain dari kelas gaya "baru" dapat ditemukan sini.

Salah satu kelemahan kelas-kelas gaya baru adalah kelas itu sendiri lebih membutuhkan memori. Kecuali Anda membuat banyak objek kelas, meskipun, saya ragu ini akan menjadi masalah dan itu tenggelam negatif di lautan positif.


Cerita Python 3.x:

Dalam Python 3, hal-hal disederhanakan. Hanya ada kelas gaya baru (yang disebut dengan jelas sebagai kelas), satu-satunya perbedaan dalam penambahan object mengharuskan Anda mengetik 8 karakter lagi. Ini:

class ClassicSpam:
    pass

benar-benar setara (terlepas dari namanya :-) untuk ini:

class NewSpam(object):
     pass

dan ini:

class Spam():
    pass

semua punya object di dalam mereka __bases__.

>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]

Jadi, apa yang harus Anda lakukan?

Dalam Python 2:  selalu mewarisi dari object secara eksplisit. Dapatkan manfaatnya.

Dengan Python 3: mewarisi dari object jika Anda menulis kode yang mencoba menjadi Python agnostic, artinya, itu perlu bekerja baik dengan Python 2 dan dengan Python 3. Jika tidak, itu benar-benar tidak ada bedanya karena Python memasukkannya untuk Anda di belakang layar.


243
2017-07-12 15:34



Python 3.x:
class MyClass(object): = kelas gaya baru
class MyClass: = kelas gaya baru (secara implisit mewarisi dari objek)

Python 2.x:
class MyClass(object): = kelas gaya baru
class MyClass: = KELAS OLD-STYLE

Penjelasan:

Saat mendefinisikan kelas dasar dengan Python 3.x, Anda diizinkan untuk menghapus objek dari definisi. Namun, ini dapat membuka pintu untuk masalah yang sulit dilacak ...

Python memperkenalkan kelas-gaya baru kembali ke Python 2.2, dan sekarang kelas-kelas gaya lama benar-benar cukup tua. Diskusi kelas gaya lama adalah terkubur dalam dokumen 2.x, dan tidak ada dalam dokumen 3.x.

Masalahnya adalah, sintaks untuk kelas gaya lama dengan Python 2.x adalah sama dengan sintaks alternatif untuk kelas-gaya baru dengan Python 3.x. Python 2.x masih sangat banyak digunakan (misalnya GAE, Web2Py), dan kode apa pun (atau coder) tanpa disadari membawa definisi kelas 3.x-gaya ke dalam kode 2.x akan berakhir dengan beberapa objek dasar yang benar-benar usang. Dan karena kelas gaya lama tidak ada di radar siapa pun, mereka mungkin tidak akan tahu apa yang menimpa mereka.

Jadi, sebutkan saja caranya dan simpan beberapa pengembang 2.x air mata.


494
2018-02-25 21:15



Ya, ini adalah objek 'gaya baru'. Itu adalah fitur yang diperkenalkan pada 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 bagus tentang kelas gaya baru.

Tautan SO untuk deskripsi tentang perbedaan: Apa perbedaan antara gaya lama dan kelas gaya baru dengan Python?


388
2017-10-25 14:20



Riwayat dari Pelajari Python the Hard Way:

Penampilan asli Python dari sebuah kelas rusak dalam banyak hal serius   cara. Pada saat kesalahan ini diketahui 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 tepat.

Mereka memutuskan bahwa mereka akan menggunakan kata "objek", diturunkan, untuk menjadi   "kelas" yang Anda warisi untuk membuat kelas. Ini membingungkan,   tetapi kelas mewarisi dari kelas bernama "objek" untuk membuat kelas tetapi   itu bukan objek yang benar-benar kelasnya, tapi 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 itu 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 bergaya 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 dapat, tentu saja, mewarisi dari satu sama lain. Mewarisi dari objek menjamin bahwa fungsi tertentu tersedia di setiap kelas Python. Kelas gaya baru diperkenalkan dengan Python 2.2


29
2017-11-04 10:54



Ya, ini historis. Tanpa itu, ia menciptakan kelas gaya lama.

Jika Anda menggunakan type() pada objek gaya lama, Anda hanya mendapatkan "instance". Pada objek gaya baru yang Anda dapatkan kelasnya.


23
2017-10-25 14:20



Sintaks pernyataan pembuatan kelas:

class <ClassName>(superclass):
    #code follows

Dengan tidak adanya superclasses lain yang secara khusus ingin Anda warisi, maka superclass harus selalu demikian object, yang merupakan akar dari semua kelas dengan Python.

object secara teknis adalah akar dari kelas "gaya baru" dengan Python. Tetapi kelas-kelas gaya baru saat ini sama bagusnya dengan satu-satunya gaya kelas.

Tapi, jika Anda tidak menggunakan kata secara eksplisit object saat membuat kelas, maka seperti yang disebutkan orang lain, Python 3.x secara implisit mewarisi dari object superclass. Tapi saya kira eksplisit selalu lebih baik daripada implisit (neraka)

Referensi


6
2017-10-20 05:37



Ini menciptakan sebuah kelas gaya baru.


1
2017-10-25 14:20