Python Academy · leksjon

__slots__ og minneoptimalisering

Bruk __slots__ til å redusere minneoverhead per instans.

Leksjon 4 av 413 trinn

__slots__ og minneoptimalisering er en gratis leksjon i Python Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Python Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Python Academy inneholder totalt 4 leksjoner.

Overhead for __dict__ som standard

Som standard lagrer hver Python-instans attributter i en __dict__-ordbok, noe som gir betydelig minneoverhead – vanligvis 200–400 byte per instans.

import sys

class Point:
    def __init__(self, x, y): self.x, self.y = x, y

p = Point(1, 2)
print(sys.getsizeof(p.__dict__))   # ~200 bytes

Deklarere __slots__

Definer __slots__ som en sekvens med attributtnavn. Python allokerer en matrise med fast størrelse i stedet for en dict, noe som sparer minne.

class SlottedPoint:
    __slots__ = ("x", "y")

    def __init__(self, x, y):
        self.x = x
        self.y = y

p = SlottedPoint(1, 2)
print(p.x, p.y)   # 1 2
# p.z = 3   # AttributeError: no __dict__

Minnesparing

Med __slots__ bruker hver instans vanligvis 30–50 % mindre minne enn en dict-basert instans – en betydelig forskjell når millioner av objekter opprettes.

import sys

class Reg:
    def __init__(self, x, y): self.x, self.y = x, y

class Slotted:
    __slots__ = ("x","y")
    def __init__(self, x, y): self.x, self.y = x, y

print(sys.getsizeof(Reg(1,2)))      # ~56 bytes + ~200 dict
print(sys.getsizeof(Slotted(1,2)))  # ~56 bytes (no dict)

Ingen __dict__ som standard

En klasse med __slots__ har ingen __dict__, så det er ikke mulig å legge til vilkårlige attributter etter opprettelsen.

class Config:
    __slots__ = ("host", "port")
    def __init__(self, h, p): self.host, self.port = h, p

c = Config("localhost", 8080)
# c.debug = True   # AttributeError
print(hasattr(c, "__dict__"))   # False

Beholde __dict__ med __slots__

Inkluder "__dict__" i __slots__ for å beholde en dict per instans, samtidig som vanlige attributter forhåndsdeklareres som slots.

class Hybrid:
    __slots__ = ("x", "__dict__")

    def __init__(self, x):
        self.x = x

h = Hybrid(1)
h.extra = "dynamic"   # allowed
print(h.extra)

__weakref__ i __slots__

Klasser med __slots__ mister støtte for svake referanser. Legg til "__weakref__" i __slots__ for å aktivere støtten igjen.

import weakref

class Node:
    __slots__ = ("value", "__weakref__")
    def __init__(self, v): self.value = v

n = Node(42)
ref = weakref.ref(n)
print(ref())  # <Node object>

Arv og __slots__

Hvis en overordnet klasse ikke bruker __slots__, får underklassen fortsatt en __dict__. For full minnesparing må hele klassehierarkiet definere __slots__.

class Base:
    __slots__ = ("x",)

class Child(Base):
    __slots__ = ("y",)   # no __dict__

class WithoutSlots(Base):
    pass   # gets __dict__ from object

Måle minnebruk

Bruk tracemalloc eller pympler for å måle faktisk minnebruk før og etter at __slots__ er lagt til.

import tracemalloc

tracemalloc.start()
points = [SlottedPoint(i, i) for i in range(100_000)]
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"Peak: {peak/1024/1024:.1f} MB")

__slots__ og pickling

Objekter med __slots__ kan serialiseres med pickle hvis __getstate__ og __setstate__ defineres, eller ved å bruke standardprotokollen for pickle, som automatisk håndterer slots fra og med Python 3.

import pickle

class Point:
    __slots__ = ("x", "y")
    def __init__(self, x, y): self.x, self.y = x, y

p = Point(3, 4)
data = pickle.dumps(p)
p2 = pickle.loads(data)
print(p2.x, p2.y)   # 3 4

dataclasses med __slots__ — Python 3.10+

Send slots=True til @dataclass for å generere __slots__ automatisk.

from dataclasses import dataclass

@dataclass(slots=True)
class Vector:
    x: float
    y: float

v = Vector(1.0, 2.0)
print(v.x, v.y)   # 1.0 2.0
print(hasattr(v, "__dict__"))   # False

Når bør __slots__ brukes

Bruk __slots__ når millioner av instanser skal opprettes, minnet er begrenset eller hastigheten på attributtilgang er kritisk. Unngå det i klasser for generell bruk der fleksibilitet er viktigere.

# Good candidates:
# - Nodes in a large graph or tree
# - Records in a large dataset
# - High-frequency event objects

# Bad candidates:
# - Configuration objects added to ad-hoc
# - Classes that mix-in dynamic attributes

Kort kontroll

Hva skjer når det forsøkes å angi et attributt som ikke står oppført i __slots__, på en instans med slots?

Oppsummering

__slots__ erstatter instansens __dict__ med en matrise med fast størrelse og sparer 30–50 % minne. Inkluder "__dict__" eller "__weakref__" hvis de trengs. Hele arvrekken må bruke __slots__ for full minnesparing. I Python 3.10+ kan @dataclass(slots=True) brukes.

Gratis å komme i gang

Lær deg Python med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
76
Leksjoner
320

Ofte stilte spørsmål

Er leksjonen «__slots__ og minneoptimalisering» gratis?

Ja – hele teksten i «__slots__ og minneoptimalisering» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Python Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «__slots__ og minneoptimalisering»?

Bruk __slots__ til å redusere minneoverhead per instans. Du øver på Python Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Python Academy?

Ingen tidligere erfaring er nødvendig. Python Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «__slots__ og minneoptimalisering»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Python Academy-leksjonen?

Ja. Alle Python Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Hvordan Python-klasser opprettes
  2. Skrive egendefinerte metaklasser
  3. Deskriptorer: __get__, __set__, __delete__
  4. __slots__ og minneoptimalisering
← Tilbake til Python Academy