Python osztályok és objektumok: A 2026-os oktatóanyag
A legtöbb Python OOP oktatóanyag megtanítja a szintaxist, és kihagyja a mentális modellt. Ez az ellenkezőjét teszi: világos képet kapsz arról, hogy mi az osztály* futás közben, mikor kell a @dataclass-hoz nyúlni, ahelyett, hogy kézzel írnád a __init__ kifejezést, és hogyan működik a self valójában (ez nem varázslat).
Kitérünk a következőkre: a négysoros minimális életképes osztály, a „self” miért paraméter, az osztály vs. példány attribútumai (az 1. számú kezdő hiba), a hat dunder metódus, amelyet mindenhol látni fog, a „@dataclass” a modern alapértelmezett, és egy szigorú szabály arra vonatkozóan, hogy mikor hagyjuk békén az osztályokat és használjunk egyszerű függvényt.
A mentális modell: az osztály egy gyár
A Pythonban egy osztály egy objektumokat előállító gyár. Minden alkalommal, amikor meghívja a Rect(3, 4) parancsot, a Python létrehoz egy új objektumot saját tárhellyel, és visszaadja Önnek.
Ez az egész szerelő. Az osztály a tervrajz; minden Rect(...) hívás a terv új RAM-ba való bélyegzője.
A self csak egy paraméter
Az első számú zavar a JS-ből vagy a Ruby-ból érkezők számára: "self" a Pythonban explicit. Minden metódus első paramétere hivatkozás a meghívott példányra.
Tehát a „c.bump()” a „Counter.bump(c)” szintaktikai cukra. A Python első argként adja át a példányt. Nevezheted "én", "this" vagy "foo" - az "én" megegyezés, nem kulcsszó. Ragaszkodjon a „self”-hez (PEP 8), hogy a többi Python-fejlesztő elolvashassa a kódját.
Az osztály vs példány attribútum csapda
A leggyakoribb Python OOP hiba a kezdő kódbázisban:
Az items = [] az osztály hatókörében EGY listát hoz létre, amelyet minden példány megoszt. Az a.add("milk") mutálja, így a b.items ugyanazt a listát látja.
Szabály: inicializálja a módosítható állapotot a `__init__` paraméterben, nem az osztály hatókörén.
Ezt a hibát többször szállították élesre, mint azt bármelyik Python-fejlesztő elismerné. Figyelje a listákat, diktátumokat, halmazokat az osztályok hatókörében.
A hat módszer, amelyet mindenhol látni fog
A Dunder metódusok (__name__) a Python operátor túlterhelési hookai. Ez a hat lefedi annak 95%-át, amivel találkozni fog:
1. __init__(self, ...) — konstruktor
Az objektum létrehozásakor fut. Itt állíthatja be a példányattribútumokat. Ne adjon vissza semmit (Python kényszeríti a "Nincs" beállítást).
2. __repr__(self) – fejlesztői karakterlánc
A print(x) hívja, ha a __str__ hiányzik, és mindig a REPL. Törekedjen valamire, amit vissza illeszthet a Pythonba az objektum újbóli létrehozásához:
3. __eq__(self, other) — egyenlőség
Enélkül a Rect(3, 4) == Rect(3, 4) False-t ad vissza (az alapértelmezés az azonosság). Hasonlítsa össze mezőnként:
4. __hash__(self) — hashability
Ha felülbírálja az __eq__ értéket, felül KELL bírálnia a __hash__ értéket is, vagy a Python beállítja a __hash__ = None értéket (az objektum kivonatolhatatlanná válik). A legegyszerűbb: return hash((self.width, self.height))`.
5. __len__(self) – len(obj)
Működőképessé teszi a len(cart) == 5 funkciót.
6. __iter__(self) — for x in obj:
Egy iterátor visszaadása. A belső hozam iterálhatóvá teszi az osztályt:
@dataclass — a modern alapértelmezett
Ha az osztályod többnyire adattartó (három mező, egy __init__, egy __repr__, egy __eq__), ne írd le ezt a sablont. A @dataclass mindezt az Ön típusjegyzeteiből generálja:
Ez az __init__, __repr__ és __eq__ mind generált. Adja hozzá a @dataclass(frozen=True) karakterláncot, hogy az objektum megváltoztathatatlan legyen ÉS a __hash__ ingyenes legyen.
Szabály: először nyúljon a `@dataclass`-hoz. Csak akkor írjon kézzel görgetett osztályt, ha olyan metódusokra van szüksége, amelyek nem attribútum-elfogadók.
__slots__ — memóriaoptimalizálás (speciális)
Alapértelmezés szerint minden példány tartalmaz egy __dict__ karakterláncot, így tetszőleges attribútumokat adhat hozzá. A __slots__ csereprogramok rögzített C-szintű struktúrát írnak elő – kisebb RAM-terület és gyorsabb attribútum-hozzáférés:
Használja a __slots__ attribútumot, ha: (a) több millió példányt hoz létre, és a RAM számít, vagy (b) futás közben szeretné elkapni az elgépelt attribútum-hozzárendelést. Ellenkező esetben hagyja ki – alapértelmezés szerint letiltja a savanyúságot, és finom módon megszakítja a többszörös öröklődést.
Mikor hagyjuk békén az órákat
Kemény szabály: ha az osztályban EGY metódus van plusz `__init__`, akkor valószínűleg függvénynek kell lennie.
Az osztályok akkor érik el súlyukat, ha több metódushíváson keresztül rendelkeznek az state értékkel, vagy ha jól definiált protokollt implementálnak (__iter__, __enter__, __eq__ stb.). Az egyszeri logika egy függvény.
Öröklődés – használja takarékosan
Az öröklés valódi, de túlzottan használt. A 2026-os Pythonban előnyben részesítse a kompozíciót – tartson egy másik objektumot attribútumként ahelyett, hogy örökölne belőle:
Csak akkor örökölj, ha valódi „is-a” kapcsolatod van, ÉS felül akarod írni a viselkedést. A 'NamedRect', amely a 'Rect'-ből öröklődik, és hozzáad egy "name" mezőt, megfelelő. Az ötszintű öröklődési hierarchia felépítése egy üzleti logikai osztályhoz olyan kód, amelyet 6 hónapon belül kibogozni fog.
Az osztályok a Python egyik leghatékonyabb funkciója, és az egyik legkönnyebben túlhasználható. A mentális modell, amely segít: az osztály az objektumok gyára, a "self" egy egyszerű paraméter, a változtatható állapot a "__init__"-ba kerül, először érje el a "@dataclass"-t, és térjen vissza egy függvényre, ha az osztálynak kevesebb, mint két állapothordozó metódusa van.
Következő lépés: 30 gyakorlati OOP lecke az osztályokról, a @dataclass-ról, az öröklődés vs összetételről és a dunder metódusokról – valódi Python futtatásával a böngészőben, és mesterséges intelligencia-mentorral minden lépésnél.