Există vreun motiv pentru ca o declarație de clasă să moștenească de la object
?
Tocmai am găsit un cod care face asta și nu găsesc un motiv bun pentru care.
class MyClass(object):
# class code follows...
Există vreun motiv pentru ca o declarație de clasă să moștenească de la object
?
Tocmai am găsit un cod care face asta și nu găsesc un motiv bun pentru care.
class MyClass(object):
# class code follows...
Există vreun motiv pentru ca o declarație de clasă să moștenească de la
object
?
În Python 3, în afară de compatibilitatea dintre Python 2 și 3, niciun motiv. În Python 2, multe motive.
În Python 2.x (de la 2.2 în sus) există două stiluri de clase în funcție de prezența sau absența lui object
ca clasă de bază:
Clasele stil „clasic”: nu au object
ca clasă de bază:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
Clase de stil „nou”: au, direct sau indirect (de exemplu, moștenesc dintr-o tip încorporat), object
ca clasă de bază:
>>> 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'>,)
Fără îndoială, atunci când scrii o clasă, vei dori întotdeauna să mergi la cursuri în stil nou. Avantajele de a face acest lucru sunt numeroase, pentru a enumera câteva dintre ele:
Suport pentru descriptori. În mod specific, următoarele constructe sunt posibile cu descriptori:
classmethod
: A method that receives the class as an implicit argument instead of the instance.staticmethod
: o metodă care nu primește argumentul implicit self
ca primă argument.property
: creați funcții pentru a gestiona obținerea, setarea și ștergerea un atribut.__slots__
: salvează consumul de memorie al unei clase și, de asemenea, duce la un acces mai rapid la atribute . Desigur, impune limitări.Metoda statică __new__
: vă permite să personalizați modul în care sunt noile instanțe de clasă creată.
Ordinea de rezoluție a metodei (MRO): în ce ordine clasele de bază ale unei clase va fi căutat atunci când încercați să rezolvați ce metodă să apelați.
Legat de MRO, super
apeluri. Consultați, de asemenea, super()
considerat super.
Dacă nu moșteniți de la object
, uitați de acestea. O descriere mai exhaustivă a punctelor anterioare, împreună cu alte avantaje ale claselor de stil „noi” poate fi găsită aici.
Unul dintre dezavantajele claselor de stil nou este că clasa în sine necesită mai multă memorie. Cu toate acestea, dacă nu creați multe obiecte de clasă, mă îndoiesc că aceasta ar fi o problemă și este o scufundare negativă într-o mare de aspecte pozitive.
În Python 3, lucrurile sunt simplificate. Există doar clase de stil nou (denumite în mod simplu clase), așa că singura diferență în adăugarea lui object
este să vă cereți să introduceți încă 8 caractere. Acest:
class ClassicSpam:
pass
este complet echivalent (în afară de numele lor :-) cu acesta:
class NewSpam(object):
pass
si la asta:
class Spam():
pass
Toți au object
în __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
În Python 2: moșteniți întotdeauna de la object
în mod explicit. Obțineți beneficiile.
În Python 3: moșteniți din object
dacă scrieți cod care încearcă să fie agnostic Python, adică trebuie să funcționeze atât în Python 2, cât și în Python 3. În caz contrar, nu, nicio diferență, deoarece Python îl inserează pentru tine în spatele scenei.
object
. IIRC a existat un moment în care nu toate tipurile încorporate au fost portate la clase de stil nou.
- person bruno desthuilliers; 19.03.2018
object
. Am un Python 2.2.3 și după o verificare rapidă nu am putut găsi un infractor, dar voi reformula răspunsul mai târziu pentru a fi mai clar. M-ar interesa totuși dacă ați găsi un exemplu, curiozitatea mea este stârnită.
- person Dimitris Fasarakis Hilliard; 20.03.2018
object
în bazele sale.
- person bruno desthuilliers; 20.03.2018
staticmethod
și classmethod
funcționează bine chiar și la cursurile de stil vechi. property
sorta funcționează pentru citire pe clase de stil vechi, pur și simplu nu reușește să intercepteze scrierile (deci dacă atribuiți numelui, instanța câștigă un atribut al numelui dat care umbrește proprietatea). De asemenea, rețineți că îmbunătățirea vitezei de acces la atribute de către __slots__
se referă în principal la anularea pierderii pe care o implică accesul la atribute de clasă de stil nou, deci nu este cu adevărat un punct de vânzare al claselor de stil nou (economiile de memorie sunt totuși un punct de vânzare).
- person ShadowRanger; 02.04.2019
Python 3
class MyClass(object):
= clasă în stil nouclass MyClass:
= clasă în stil nou (moștenește implicit de la object
)Python 2
class MyClass(object):
= clasă în stil nouclass MyClass:
= CLASA DE STIL VECHIExplicație:
Când definiți clase de bază în Python 3.x, aveți voie să eliminați object
din definiție. Cu toate acestea, acest lucru poate deschide ușa pentru o problemă serios greu de urmărit...
Python a introdus clase de stil nou în Python 2.2, iar până acum clasele de stil vechi sunt într-adevăr destul de vechi. Discuția despre clasele în stil vechi este îngropată în cele 2 documente .x și inexistente în documentele 3.x.
Problema este că sintaxa pentru clasele în stil vechi în Python 2.x este aceeași cu sintaxa alternativă pentru clasele în stil nou în Python 3.x. Python 2.x este încă folosit pe scară largă (de exemplu, GAE, Web2Py), și orice cod (sau programator) care aduce fără să vrea definiții de clasă în stil 3.x în codul 2.x se va termina cu niște obiecte de bază serios învechite. Și pentru că cursurile în stil vechi nu sunt pe radarul nimănui, probabil că nu vor ști ce i-a lovit.
Așa că scrieți-l pe cale lungă și salvați lacrimile unor dezvoltatori 2.x.
__metaclass__ = type
în partea de sus a modulului (după linia from __future__ import absolute_import, division, print_function
:-) ); este un hack de compatibilitate în Py2 care face ca toate clasele definite ulterior în modul să fie în stil nou în mod implicit, iar în Py3, este complet ignorat (doar o variabilă globală aleatorie), așa că este inofensiv.
- person ShadowRanger; 09.12.2016
Da, acesta este un obiect de „stil nou”. A fost o caracteristică introdusă în python2.2.
Obiectele de stil noi au un model de obiect diferit de obiectele clasice, iar unele lucruri nu vor funcționa corect cu obiectele de stil vechi, de exemplu, super()
, @property
și descriptori. Consultați acest articol pentru o descriere bună a ceea ce este nou clasa de stil este.
Link SO pentru o descriere a diferențelor: Care este diferența dintre stilul vechi și noi clase de stil în Python?
object
în Python 2.
- person ; 25.10.2010
Istoricul de la Învățați Python pe calea grea:
Redarea originală a unei clase de către Python a fost ruptă în multe moduri serioase. Până când a fost recunoscută această greșeală, era deja prea târziu și au trebuit să o susțină. Pentru a rezolva problema, aveau nevoie de un stil de „clasă nouă”, astfel încât „clasele vechi” să continue să funcționeze, dar puteți folosi noua versiune mai corectă.
Au decis că vor folosi un cuvânt „obiect”, cu litere mici, pentru a fi „clasa” de la care moștenești pentru a face o clasă. Este confuz, dar o clasă moștenește din clasa numită „obiect” pentru a face o clasă, dar nu este un obiect, de fapt, este o clasă, dar nu uitați să moșteniți de la obiect.
De asemenea, doar pentru a vă anunța care este diferența dintre clasele în stil nou și clasele în stil vechi, este că clasele în stil nou moștenesc întotdeauna de la clasa object
sau de la o altă clasă care a moștenit de la object
:
class NewStyle(object):
pass
Un alt exemplu este:
class AnotherExampleOfNewStyle(NewStyle):
pass
În timp ce o clasă de bază în stil vechi arată astfel:
class OldStyle():
pass
Și o clasă pentru copii în stil vechi arată astfel:
class OldStyleSubclass(OldStyle):
pass
Puteți vedea că o clasă de bază Old Style nu moștenește de la nicio altă clasă, totuși, clasele Old Style pot, desigur, să moștenească una de la alta. Moștenirea de la obiect garantează că anumite funcționalități sunt disponibile în fiecare clasă Python. Au fost introduse noi clase de stil în Python 2.2
object
nu este chiar atât de confuză și, de fapt, este destul de standard. Smalltalk are o clasă rădăcină numită Object
și o metaclasă rădăcină numită Class
. De ce? Pentru că, la fel cum Dog
este o clasă pentru câini, Object
este o clasă pentru obiecte, iar Class
este o clasă pentru clase. Java, C#, ObjC, Ruby și majoritatea celorlalte limbaje OO bazate pe clasă pe care oamenii le folosesc astăzi și care au o clasă rădăcină folosesc o variație a Object
ca nume, nu doar Python.
- person abarnert; 04.05.2015
Da, este istoric. Fără el, se creează o clasă în stil vechi.
Dacă utilizați type()
pe un obiect în stil vechi, obțineți doar „instanță”. Pe un obiect de stil nou obțineți clasa sa.
type()
pe o clasă de stil vechi, obțineți classobj în loc de type.
- person Joel Sjögren; 15.02.2014
Sintaxa instrucțiunii de creare a clasei:
class <ClassName>(superclass):
#code follows
În absența oricăror alte superclase de la care doriți să moșteniți, superclass
ar trebui să fie întotdeauna object
, care este rădăcina tuturor claselor în Python.
object
este din punct de vedere tehnic rădăcina claselor de „stil nou” în Python. Dar cursurile de tip nou de astăzi sunt la fel de bune ca fiind singurul stil de cursuri.
Dar, dacă nu folosiți în mod explicit cuvântul object
atunci când creați clase, atunci, așa cum au menționat alții, Python 3.x moștenește implicit din superclasa object
. Dar cred că explicit este întotdeauna mai bine decât implicit (la naiba)