Clase și obiecte Python: Tutorialul 2026
Majoritatea tutorialelor Python OOP predau sintaxa și omit modelul mental. Acesta face opusul — veți pleca cu o imagine clară a ceea ce este o clasă în timpul execuției, când să ajungeți la @dataclass în loc să scrieți __init__ de mână și cum funcționează cu adevărat self (nu este magie).
Vom acoperi: clasa viabilă minimă de patru linii, de ce self este un parametru, atribute clasă vs instanță (bunul pentru începători numărul 1), cele șase metode dunder pe care le veți vedea peste tot, @dataclass ca implicită modernă și o regulă strictă pentru când să lăsați clasele în pace și să utilizați o funcție simplă.
Modelul mental: o clasă este o fabrică
O clasă în Python este o fabrică care produce obiecte. De fiecare dată când apelați Rect(3, 4), Python creează un obiect nou cu propriul său spațiu de stocare și vi-l predă înapoi.
Acesta este întregul mecanic. Clasa este planul; fiecare apel „Rect(...)” este o ștampilă a planului în RAM proaspătă.
self este doar un parametru
Confuzia numărul 1 pentru persoanele care vin din JS sau Ruby: self în Python este explicit. Primul parametru al fiecărei metode este o referință la instanța apelată.
Deci c.bump() este zahăr sintactic pentru Counter.bump(c). Python trece instanța ca prim argument. L-ați putea numi eu, this sau foo — self este o convenție, nu un cuvânt cheie. Rămâneți cu self (PEP 8) pentru ca alți dezvoltatori Python să vă poată citi codul.
Capcana atributului clasă vs instanță
Cea mai comună eroare Python OOP într-o bază de cod pentru începători:
items = [] la domeniul de aplicare al clasei creează O listă partajată de fiecare instanță. a.add("lapte") îl modifică, astfel încât b.items vede aceeași listă.
Regulă: inițializați starea mutabilă în `__init__`, nu în domeniul de aplicare al clasei.
Acest bug a fost livrat în producție de mai multe ori decât va admite orice dezvoltator Python. Urmăriți liste, dictări, seturi la nivelul clasei.
Cele șase metode pe care le vei vedea peste tot
Metodele Dunder (__name__) sunt cârlige de supraîncărcare a operatorului Python. Aceste șase acoperă 95% din ceea ce vei întâlni:
1. __init__(self, ...) — constructor
Se rulează când obiectul este creat. Setați aici atributele instanței. Nu returnați nimic (Python impune Niciuna).
2. __repr__(self) — șir orientat către dezvoltator
Apelat de print(x) dacă lipsește __str__ și întotdeauna de REPL. Țintește ceva pe care să-l inserezi înapoi în Python pentru a recrea obiectul:
3. __eq__(self, other) — egalitate
Fără el, Rect(3, 4) == Rect(3, 4) returnează False (implicit este identitatea). Comparați câmp cu câmp:
4. __hash__(self) — hashability
Dacă suprascrieți __eq__, TREBUIE să suprascrieți, de asemenea, __hash__ sau seturile Python __hash__ = None (obiectul devine neschimbabil). Cel mai simplu: return hash((self.width, self.height)).
5. __len__(self) — pentru len(obj)
Face ca len(cart) == 5 să funcționeze.
6. __iter__(self) — pentru for x in obj:
Returnează un iterator. yield în interior face clasa iterabilă:
@dataclass — implicit modern
Dacă clasa dvs. este în mare parte un deținător de date (trei câmpuri, un __init__, un __repr__, un __eq__), nu mai scrieți acel boilerplate. @dataclass generează totul din adnotările dvs. de tip:
Acestea sunt __init__, __repr__ și __eq__ toate generate. Adăugați @dataclass(frozen=True) pentru a face obiectul imuabil ȘI pentru a obține __hash__ liber.
Regulă: ajungeți mai întâi la `@dataclass`. Scrieți o clasă rulată manual numai atunci când aveți nevoie de metode care nu sunt accesorii de atribute.
__slots__ — optimizare memorie (avansat)
În mod implicit, fiecare instanță poartă un __dict__, astfel încât să puteți adăuga atribute arbitrare. __slots__ schimbă care dictează pentru o structură fixă de nivel C - amprentă RAM mai mică și acces mai rapid la atribute:
Folosiți __slots__ atunci când: (a) creați milioane de instanțe și RAM contează sau (b) doriți să identificați atribuirea atributelor greșite în timpul execuției. În caz contrar, omiteți-l - dezactivează implicit murătura și rupe moștenirea multiplă în moduri subtile.
Când să părăsești cursurile în pace
Regulă grea: dacă clasa ta are O metodă plus `__init__`, probabil că ar trebui să fie o funcție.
Clasele își câștigă greutatea atunci când dețin state în mai multe apeluri de metodă sau când implementează un protocol bine definit (__iter__, __enter__, __eq__ etc.). Logica unică este o funcție.
Moștenire — folosiți-o cu moderație
Moștenirea este reală, dar suprautilizată. În 2026 Python, preferați compoziție - păstrați un alt obiect ca atribut în loc să moșteniți de la acesta:
Moșteniți numai atunci când aveți o relație autentică „este o” ȘI doriți să treceți peste comportament. Un NamedRect care moștenește de la Rect pentru a adăuga un câmp name este bine. Construirea unei ierarhii de moștenire pe cinci niveluri pentru o clasă de logică de afaceri este un cod pe care îl veți descurca în 6 luni.
Clasele sunt una dintre cele mai puternice caracteristici ale Python și una dintre cele mai ușor de suprautilizat. Modelul mental care ajută: o clasă este o fabrică de obiecte, self este un parametru simplu, starea mutabilă merge în __init__, ajunge mai întâi la @dataclass și reîntoarce-te la o funcție ori de câte ori clasa are mai puțin de două metode purtătoare de stare.
Următorul pas: 30 de lecții practice OOP care acoperă clase, @dataclass, moștenire vs compoziție și metode dunder - cu Python real rulând în browser și un mentor AI la fiecare pas.